UNIX網(wǎng)絡(luò)編程筆記
做下筆記,以供不時之需:)
第4章
socket(int family, int type, int protocol);
非負(fù)描述字-成功,-1-出錯
協(xié)議族 套接口類型 協(xié)議類型常量值
AF_INET IPv4協(xié)議 SOCK_STREAM 字節(jié)流 IPPROTO_TCP TCP傳輸協(xié)議
AF_INET6 IPv6協(xié)議 SOCK_DGRAM 數(shù)據(jù)報 IPPROTO_UDP UDP傳輸協(xié)議
AF_LOCAL UNIX域協(xié)議 SOCK_SEQPACKET有序分組 IPPROTO_SCTP SCTP傳輸協(xié)議
AF_ROUTE 路由套接口 SOCK_RAW 原始套接口
AF_KEY 密鑰套接口
protocol可以設(shè)為0,以選擇所給定的family和type組合的系統(tǒng)缺省值
connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
要連接的套接口描述字 指向描述連接地址的套接口地址的結(jié)構(gòu)指針 指向套接口地址的結(jié)構(gòu)大小
0-成功,-1-失敗
ETIMEDOUT錯誤,客戶端未收到SYN分節(jié)的響應(yīng)
在4.4BSD內(nèi)核中SYN分節(jié)會在首次發(fā)出后的6秒,24秒后再發(fā)出SYN分節(jié),如果75秒后仍無響應(yīng),返回錯誤(TCPv2 p828)
ECONNERFUSED錯誤,客戶端收到RST分節(jié)時就返回錯誤
其中產(chǎn)生RST的三個條件是:
1.目的地為某端口的SYN到達(dá),然而該端口上沒有正在監(jiān)聽的服務(wù)器
2.TCP想取消一個已有連接
3.TCP接受到一個根本不存在的連接上的分節(jié)(TCPv1 246-250)
EHOSTUNREACH或ENETUNREACH錯誤
在發(fā)出SYN分節(jié)的中間某個路由器引發(fā)了目的地不可達(dá)的ICMP錯誤,客戶主機(jī)保存該消息,但仍然繼續(xù)發(fā)送SYN,直到75秒后,如果仍未有回應(yīng),則把錯誤消息返回給進(jìn)程。
以下情況也會產(chǎn)生此類錯誤
1.本地系統(tǒng)的轉(zhuǎn)發(fā)表,根本沒有到達(dá)遠(yuǎn)地系統(tǒng)的路徑
2.connect調(diào)用根本不等待就返回(非阻塞?)
注:connect失敗則該套接口不再可用,必須關(guān)閉。
bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
0-成功,-1失敗
要綁定的套接口描述字 指向描述要綁定的套接口地址的結(jié)構(gòu)指針 指向套接口地址的結(jié)構(gòu)大小
如果一個TCP客戶端或服務(wù)器未曾調(diào)用bind捆綁一個端口,當(dāng)調(diào)用connect或listen時,內(nèi)核會為相應(yīng)的套接口選擇一個臨時端口
進(jìn)程可把特定IP地址捆綁到它的套接口上,這個特定IP必須是主機(jī)的網(wǎng)絡(luò)接口之一。對于TCP客戶,這就限定了套接口只接受目的地為這個特定IP的客戶連接。
TCP客戶通過不把IP捆綁到它的套接口上,內(nèi)核會根據(jù)所用外出網(wǎng)絡(luò)接口來選擇源IP地址,而所用外出的接口則取決于到達(dá)服務(wù)器所需的路徑。(TCPv2 p737)
如果TCP服務(wù)器沒有把IP地址捆綁到它的套接口上,內(nèi)核就把客戶發(fā)送的SYN的宿IP地址作為服務(wù)器的源地址。(TCPv2 p943)
EADDRINUSE錯誤 地址已使用
listen( int sockfd , int backlog);
0-成功,-1失敗
要轉(zhuǎn)換成被動的套接口 排隊的最大已連接個數(shù)
1.未完成連接隊列
處于SYN_RCVD狀態(tài)的套接口隊列
2.已完成連接隊列
處于ESTABLISHED狀態(tài)的套接口隊列
在隊列滿時,服務(wù)器如果收到SYN分節(jié),會忽略掉,因為隊列滿是暫時性的,忽略掉可以以期待客戶端的再次連接。而如果返回RST分節(jié),會時客戶端放棄連接。
在三次握手完成之后,但在服務(wù)器調(diào)用accept之前到達(dá)的數(shù)據(jù),應(yīng)有服務(wù)器TCP排隊,最大數(shù)據(jù)量為相應(yīng)的已連接套接口的接受緩沖區(qū)大小。
Int accept( int sockfd, struct sockaddr* cliaddr, socklen_t* addrlen);
非負(fù)描述字-成功,-1-失敗
被動的監(jiān)聽套接口 對端的套接口地址的結(jié)構(gòu) 對端的套接口地址的結(jié)構(gòu)大小
Int close(int sockfd);
0- 成功,-1-失敗
要關(guān)閉的套接口
缺省行為是修改套接口標(biāo)記為已關(guān)閉,函數(shù)會立即返回,此時該套接口描述字已不能再由進(jìn)程使用。而TCP將嘗試發(fā)送已排隊等待發(fā)送到對端的任何數(shù)據(jù),發(fā)送完畢后開始正常的TCP連接終止序列。
SO_LINGER套接口選項可以改變此缺省行為。