Linux系統是經過提供套接字(socket)來進行網絡編程的.網絡程序經過socket和其它幾個函數的調用,會返回一個 通信的文件描述符,咱們能夠將這個描述符當作普通的文件的描述符來操做,這就是linux的設備無關性的好處.
咱們能夠經過向描述符讀寫操做實現網絡之間的數據交流. linux
1.socket web
int socket(int domain, int type,int protocol)編程
domain:說明咱們網絡程序所在的主機採用的通信協族(AF_UNIX和AF_INET等).
AF_UNIX只可以用於單一的Unix 系統進程間通訊,
而AF_INET是針對Internet的,於是能夠容許在遠程
主機之間通訊(當咱們 man socket時發現 domain可選項是 PF_*而不是AF_*,由於glibc是posix的實現因此用PF代替了AF, 不過咱們均可以使用的).服務器
type:咱們網絡程序所採用的通信協議(SOCK_STREAM,SOCK_DGRAM等)
SOCK_STREAM代表咱們用的是TCP 協議,這樣會提供按順序的,可靠,雙向,面向鏈接的比特流.
SOCK_DGRAM 代表咱們用的是UDP協議,這樣只會提供定長的,不可靠,無鏈接的通訊.網絡
protocol:因爲咱們指定了type,因此這個地方咱們通常只要用0來代替就能夠了 socket爲網絡通信作基本的準備.
成功時返回文件描述符,失敗時返回-1,看errno可知道出錯的詳細狀況.dom
2.bind
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)socket
sockfd:是由socket調用返回的文件描述符.函數
addrlen:是sockaddr結構的長度.spa
my_addr:是一個指向sockaddr的指針. 在中有 sockaddr的定義指針
struct sockaddr{
unisgned short as_family;
char sa_data[14];
};
不過因爲系統的兼容性,咱們通常不用這個頭文件,而使用另一個結構(struct sockaddr_in) 來代替.在中有sockaddr_in的定義
struct sockaddr_in{
unsigned short sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
}
咱們主要使用Internet因此
sin_family通常爲AF_INET,
sin_addr設置爲INADDR_ANY表示能夠和任何的主機通訊,
sin_port是咱們要監聽的端口號.sin_zero[8]是用來填充的.
bind將本地的端口同socket返回的文件描述符捆綁在一塊兒.成功是返回0,失敗的狀況和socket同樣
3.listen
int listen(int sockfd,int backlog)
sockfd:是bind後的文件描述符.
backlog:設置請求排隊的最大長度.當有多個客戶端程序和服務端相連時, 使用這個表示能夠介紹的排隊長度.
listen函數將bind的文件描述符變爲監聽套接字.返回的狀況和bind同樣.
4.accept
int accept(int sockfd, struct sockaddr *addr,int *addrlen)
sockfd:是listen後的文件描述符.
addr,addrlen是用來給客戶端的程序填寫的,服務器端只要傳遞指針就能夠了. bind,listen和accept是服務器端用的函數,
accept調用時,服務器端的程序會一直阻塞到有一個 客戶程序發出了鏈接. accept成功時返回最後的服務器端的文件描述符,
這個時候服務器端能夠向該描述符寫信息了. 失敗時返回-1
5.connect
int connect(int sockfd, struct sockaddr * serv_addr,int addrlen)
sockfd:socket返回的文件描述符.
serv_addr:儲存了服務器端的鏈接信息.其中sin_add是服務端的地址
addrlen:serv_addr的長度
connect函數是客戶端用來同服務端鏈接的.成功時返回0,sockfd是同服務端通信的文件描述符 失敗時返回-1.