Linux 套接字編程-基礎總結

這兩天一直在看《linux C編程實戰》網路編程一章,主要研究的是套接字編程這部分。裏面的大部分程序自己都上機驗證了。最後的一個綜合應用,服務器/客戶端 程序自己也是親自敲進電腦的。也許敲的過程就是一種學習,可以發現裏面一些細節上的問題,這是光看發現不了的。根據這本書的講解,再依據對最後這個應用程序的理解,自己把套接字編程的需要注意的地方總結下。


套接字地址結構

結構struct sockaddr 定義了一種通用的套接字地址,它的類型是:

struct sockaddr

{

    unsigned short sa_family;      //地址類型,一般爲AF_INET

    char           sa_data[14];    //14字節的協議地址

};

這是一種通用的定義,一般都不用。TCP/IP使用的是自己的結構體struct sockaddr_in,格式如下:

struct sockaddr_in

{

    unsigned short sin_family;      //地址類型,一般爲AF_INET

    unsigned short sin_port;        //端口號

    struct in_addr sin_addr;        //IP地址

    unsigned char  sin_zero[8];     //填充字節,一般賦值爲0。爲了使結構體長度達到16字節,匹配結構體sockaddr

};

這裏的struct in_addr的定義如下:

struct in_addr

{

    unsigned long  s_addr;

};

結構體sockaddr和sockaddr_in的長度都是16字節。一般在編TCP/IP程序時,一般使用結構體sockaddr_in來設置地址,然後在需要的時候,通過強制類型轉換成sockaddr類型。

 

創建套接字

socket函數用來創建一個套接字,函數原型:

int socket(int domain, int type, int protocol);

參數domain指定創建套接字所使用的協議族;

參數type指定套接字的類型;

參數protocol通常設置爲0。

函數執行成功,返回一個新創建的套接字,錯誤返回-1。


 

建立連接

函數connect用來在一個指定的套接字上創建一個連接,函數原型:

int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);

參數sockfd是一個由函數socket創建的套接字;

參數serv_addr是一個地址結構,需要連接的地址;

參數addrlen爲參數addr_addr的長度。

函數執行成功返回0,有錯誤發生則返回-1。

如果套接字類型是TCP,則該函數用於向服務器發出連接請求,服務器的IP地址和端口號由參數serv_addr指定;如果套接字類型是UDP,則該函數並不建立真正的連接,它只是告訴內核與該套接字進行通信的目的地址(由第二個參數指定),只有該目的地址發來的數據纔會被該socket接收。

通常一個面向連接的套接字只能調用一次connect函數;而對於無連接的套接字則可以多次調用connect函數以改變與目的地址的綁定。

 

在套接字上監聽

函數listen把套接字轉化爲被動監聽,函數原型:

int listen(int s, int backlog);

參數s指定了一個套接字;

參數backlog指定了該連接隊列的最大長度,如果已達到最大,則之後的連接請求將被服務器拒絕。

函數執行成功趕回0,有錯誤發生則返回-1。

由函數socket創建的套接字是主動套接字,這種套接字可以用來主動請求連接到某個服務器上。(通過connect()函數)。

作爲服務器端的程序,通常在某個端口上監聽等待來自客戶端的連接請求。在服務器端,一般是先調用函數socket創建一個主動套接字,然後調用函數bind將該套接字綁定到某個端口上,接着再調用函數listen將該套接字轉化爲監聽套接字,等待來自於客戶端的連接請求。

函數listen只是將套接字設置爲傾聽模式以等待連接請求,它並不能接收連接請求,真正的接收客戶端連接請求的是accept()函數。

 

接收連接

函數accept用來接收一個連接請求,函數原型:

int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

參數s是由socket創建,經函數bind綁定到本地某一端口上,然後通過函數listen轉化而來的監聽套接字;

參數addr用來保存發起連接請求的主機的地址和端口;

參數addrlen是addr所指向的結構體的大小。

函數執行成功返回一個新的代表客戶端的套接字,出錯則返回-1。

只能對面向連接的套接字使用accept函數。accept執行成功時,將創建一個新的套接字,並且這個新的套接字分配一個套接字描述符,並返回這個新的套接字描述符。這個新的套接字描述符與打開文件返回的文件描述符類似,進程可以利用這個新的套接字描述符與客戶端交換數據,參數s所指定的套接字繼續等待客戶端的連接請求。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章