TCP網路程式設計介面詳細介紹
1.socket介面(用來建立網路套接字):
int socket(int family, int type, int protocol);
引數:family 指明協議族(IPv4:AF_INET)(IPv6:AF_INET6)
type TCP只支援位元組流協議 SOCK_STREAM
protocol 標示某個協議型別常值(TCP設定為0即可)
返回值:成功返回一個非負套接字,失敗返回-1
2.connect介面(連線伺服器):
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
引數:sockfd 由socket函式返回的套接字描述符
servaddr 套接字地址結構,必須含有伺服器ip地址和埠號
addrlen 套接字地址結構長度
返回值:成功返回0,出錯返回-1
出錯情況分析:
1)TCP客戶沒有收到SYN分節的確認應答,則errno被設定為ETIMEDOUT。
2)若對客戶端SYN分節響應的RST(復位),表明伺服器在我們指定埠號上沒有程序在等待
與之連線,這是一個硬錯誤,則errno被設定為ECONNREFUSED。
RST是TCP在發生錯誤時傳送的一個分節。產生RST的三種情況:1)伺服器該埠的服務
沒有開啟。2)TCP取消一個已有連線。3)TCP接收到一個不存在的 連線上的分節。
3)客戶端SYN分節在某個路由上引發一個“destination unreachable”(目的地不可達)的ICMP
錯誤,這是一種軟錯誤。客戶端主機核心會儲存改訊息,然後按照第一 種情況的時間間隔
繼續傳送SYN分節,若是在規定時間後仍未收到響應,則把儲存的訊息(ICMP錯誤)作為
EHOSTUNREACH或者ENETUNREACH錯誤返回 給程序。
注意:這個函式是一個阻塞函式,發起三次握手,直到連線成功或者失敗才會返回。在connect失敗後,
我們不能更換服務地址和埠號,再次繼續connect,我們必須關閉之前的套接字描述符,然後
再申請新的,然後再connect。
3.bind介面(把一個本地協議地址繫結到一個套接字,本地協議地址是ip地址和埠號的組合):
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
引數:sockfd 由socket函式返回的套接字描述符
myaddr 套接字地址結構,(對於TCP,埠號和ip地址指不指定無所謂,不指定機器會自動分配)
addrlen 套接字地址結構長度
返回值:成功返回0,出錯返回-1
4.listen介面(把一個未連線的套接字轉換成一個被動套接字,指示核心應該接受指向改套接字的連線請求,
把套接字狀態從CLOSED轉到LISTEN):
int listen(int sockfd, int backlog);
引數:sockfd 由socket函式返回的套接字描述符
backlog sockfd套接字排隊的最大連線個數
返回值:成功返回0,出錯返回-1
注意:監聽套接字(LISTEN狀態套接字)維護兩個佇列:
未完成連線佇列:某個客戶端傳送SYN分節並送達伺服器,而伺服器正在等待完成相應的TCP
三路握手過程,這些套接字出於SYN_RCVD狀態。
已完成連線佇列:已完成TCP三路握手過程的連線,套接字處於ESTABLISHED狀態。
TCP為監聽套接字維護的兩個佇列圖
5.accept介面(生成與客戶端的TCP連線):
int accept(int sockfd, const struct sockaddr *cliaddr, socklen_t addrlen);
引數:sockfd 由socket函式返回的套接字描述符
cliaddr 客戶端套接字地址結構
addrlen 套接字地址結構長度
返回值:成功返回非負套接字描述符,出錯返回-1
6.close介面(關閉套接字、終止TCP連線):
int close(int sockfd);
引數:sockfd 由socket函式返回的套接字描述符
返回值:成功返回0,出錯返回-1