UNP-UNIX網絡編程 第四章:基本TCP套接字編程

1.

#include <sys/socket.h>
int socket(int family, int type, int protocol);
//返回:若成功則返回非負描述符,出錯則爲-1,family是協議族,type表明套接字類型
family參數指定協議族,也被稱爲協議域。IPV4:AF_INET、IPV6:AF_INET6。
type參數指定套接字類型。字節流:SOCK_STREAM.   數據報:SOCK_DGRAM。
protocol參數是某個協議類型常值,或者設爲0,以選擇給定family和type組合的系統默認值。
TCP:IPPROTO_TCP , UDP:IPPROTO_UDP ,SCTP:IPPROTO_SCTP 

2.

connect函數用來建立與TCP服務器的連接。

int connect (int sockfd , const struct sockaddr *servaddr , socklen_t addrlen);
成功:返回0,出錯:返回-1

Sockfd: socket返回的套接字描述符;
*servaddr :指向套接字地址結構的指針;
Addrlen:套接字地址結構的大小;

其中出錯可能有多種情況:
1.TCP客戶沒有收到SYN分節的響應,返回ETIMEOUT錯誤;
2.對客戶的SYN的響應是RST(復位),表明主機在指定端口上沒有進場等待連接,返回ECONNREFUSED錯誤;

對於TCP套接字,connect()會觸發三次握手過程;當且僅當成功連接或出錯時纔會返回。其中出錯可能有多種情況:
根據TCP轉換圖,connect()函數會使套接字從CLOSED狀態轉換到SYN_SENT狀態,若成功再轉換到ESTABLISHED狀態。若connect失敗,則該套接字不可再用,必須關閉,然後重新調用socket()函數。

3.

bind()函數把一個本地協議地址賦予一個套接字。(比如端口號)

Int bind (int sockfd ,const struct sockaddr *myaddr , soclen_t addrlen);
成功:返回0,出錯:返回-1,還可能:Addrress already in use;

*myaddr:指向套接字地址結構的指針;
Addrlen:套接字地址結構的大小;

對於TCP客戶:在該套接字上發送的IP數據報指派了源IP地址。
對於TCP服務器:限定該套接字只接收那些目的地爲這個IP地址的客戶連接。

4.

int listen (int sockfd , int backlog );

<1>當socket函數創建一個套接字時,它被假設爲一個主動套接字(它將調用connect()函數發起連接),

<2>規定內核爲相應套將字排隊的最大連接個數。(backlog)
對backlog的理解:內核爲每個監聽套接字維護兩個隊列:
<1>未完成連接隊列, <2>已完成連接隊列

5.

int accept (int sockfd , struct sockaddr *cliaddr , socklen_t* addrlen);
成功:返回非負描述符,失敗返回-1

功能:由TCP服務器調用,用於從已完成連接隊列隊頭返回下一個已完成連接。
*cliaddr、*addrlen:客戶的協議地址及對應大小。
返回的描述符代表與所返回的客戶的TCP連接,因此將sockfd稱爲監聽套接字,將返回的描述符稱爲已連接套接字。

6.

int close( int sockfd);

關閉指定的套接字連接。可以忽略這個,直接exit(-1);

7.

intgetsockname (int sockfd , struct sockaddr *localaddr , socklen_t*addrlen);
intgetpeername (int sockfd , struct sockaddr *peeraddr , socklen_t*addrlen);
成功:返回0,出錯返回-1

功能:前者返回套接字的本地端的地址結構,後者返回外地端的地址結構。
只知道connfd的時候,獲取客戶身份的唯一途徑就是調用getpeername。

<1>在沒有調用bind的TCP客戶上,connect()成功返回後,用getsockname()返回內核賦予該連接的本地IP地址和本地端口號;
<2>以端口號0調用bind(由內核選擇本地端口號)後,用getsockname()返回本地端口號;
<3>getsockname可用於獲取某個套接字的地址族;
<4>以通配IP地址調用bind的TCP服務器上,與客戶的連接建立之後(accept成功返回),
getsockname用於返回內核賦予該連接的本地IP地址。(套接字描述符必須是已連接套接字描述符)
<5>當服務器通過調用accept的某個進程調用exec執行程序時,只能通過getpeername來獲取客戶身份。

8.

pid_t fork(void);

fork調用一次,在父進程中返回一次,得到子進程的進程ID號,在子進程返回一次,返回0.
父進程在fork之前打開的所以描述符在fork返回後由子進程分享。
如果父進程在fork後得到一個自身的副本,可以調用exec函數將當前進程映像替換成新的程序文件。稱調用exec的進程爲調用進程,新執行的程序爲新程序。
exec函數只有在出錯時才返回到調用者,否則,控制就被傳遞給新程序的起始點,通常是main函數

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