Linux Socket API Connect 函数详解
在講解套接字編程函數(shù)之前,有必要對(duì)socket編程的兩個(gè)不可或缺的結(jié)構(gòu)體進(jìn)行說(shuō)明。
第一個(gè)結(jié)構(gòu)體式struct sockaddr.。這個(gè)結(jié)構(gòu)為許多類(lèi)型的套接字儲(chǔ)存套接字地址信息:
?Sockaddr結(jié)構(gòu)體介紹
? #include<sys/socket.h> ?
??
?struct sockaddr { ??
? ? ?uint8_t sa_len; ??
? ? ?unsigned short sa_family; /* 地址家族, AF_xxx */ ??
? ? ?char sa_data[14]; /*14字節(jié)協(xié)議地址*/ ?
?}; ??
由于歷史的原因,套接字函數(shù)中(如connect,bind等)使用的參數(shù)類(lèi)型大多是sockaddr類(lèi)型的。而如今進(jìn)行套接字編程的時(shí)候大都使用sockaddr_in進(jìn)行套接字地址填充
sockaddr_in結(jié)構(gòu)體介紹
?struct sockaddr_in { ??
? uint8_t sa_len; ? /* 結(jié)構(gòu)體長(zhǎng)度*/ ??
? ? ? ? ?short int sin_family; /* 通信類(lèi)型 */ ??
? unsigned short int sin_port; /* 端口 */ ??
? struct in_addr sin_addr; /* Internet 地址 */ ??
? unsigned char sin_zero[8]; /* 未使用的*/ ??
}; ?
?struct in_addr { ? //sin_addr的結(jié)構(gòu)體類(lèi)型in_addr 原型 ?
? unsigned long s_addr; ? ? /*存4字節(jié)的 IP 地址(使用網(wǎng)絡(luò)字節(jié)順序)。*/ ?
? }; ??
因此,這就要求對(duì)這些函數(shù)進(jìn)行調(diào)用的時(shí)候都必須要講套接字地址結(jié)構(gòu)指針進(jìn)行類(lèi)型強(qiáng)制轉(zhuǎn)換,例如:
1. struct sockaddr_in serv; ? ?
2. bind(sockfd,(struct sockaddr *)&serv,sizeof(serv)); ?
否則C編譯器會(huì)產(chǎn)生警告信息(把不兼容的指針類(lèi)型傳遞給“bind”函數(shù)的第二個(gè)參數(shù))。(注意sockaddr_in的sin_port和 sin_addr 必須是網(wǎng)絡(luò)字節(jié)順序 (Network Byte Order))
Conncet函數(shù)介紹
connect() 系統(tǒng)調(diào)用函數(shù)原型如下所示:
1. #include <sys/types.h>; ??
2. #include <sys/socket.h>; ?
3. int connect(int sockfd, struct sockaddr *serv_addr, int addrlen); ??
sockfd?是系統(tǒng)調(diào)用?socket()?返回的套接字文件描述符。serv_addr?是?保存著目的地端口和?IP?地址的數(shù)據(jù)結(jié)構(gòu)?struct?sockaddr。addrlen?設(shè)置?為?sizeof(struct?sockaddr)。
connect函數(shù)在調(diào)用失敗的時(shí)候返回值-1,并會(huì)設(shè)置全局錯(cuò)誤變量?errno。Connect?函數(shù)調(diào)用成功的時(shí)候返回0,并返回一個(gè)標(biāo)示此連接。客戶端就可以通過(guò)sockfd進(jìn)行與服務(wù)端的通信。
?
如果是TCP套接字,調(diào)用connect會(huì)激發(fā)TCP的三路握手過(guò)程,首先發(fā)送SYN請(qǐng)求的報(bào)文給服務(wù)端,其出錯(cuò)返回設(shè)置errno變量值有如下幾種:
(1)?若TCP沒(méi)有收到SYN分節(jié)的響應(yīng),則返回?會(huì)設(shè)置?errno變量值為ETIMEDOUT。
(2)?若對(duì)客戶的SYN的響應(yīng)是RST(表示復(fù)位),則表明該服務(wù)器主機(jī)在我們制定的端口上沒(méi)有進(jìn)程在等待與之連接(例如服務(wù)器進(jìn)程或許沒(méi)有在運(yùn)行),此時(shí)errno?會(huì)設(shè)置為ECONNREFUSED錯(cuò)誤。
(3)?若客戶發(fā)出的SYN在中間的某個(gè)路由器引發(fā)了一個(gè)ICMP錯(cuò)誤報(bào)文(例如主機(jī)不可達(dá))。客戶主機(jī)內(nèi)核會(huì)保存該信息,并按一定的時(shí)間間隔繼續(xù)發(fā)送SYN,如若在某個(gè)規(guī)定得時(shí)間內(nèi)還沒(méi)收到響應(yīng),則會(huì)把保存的消息作為EHOSTUNREACH返回給進(jìn)程。
總結(jié)
以上是生活随笔為你收集整理的Linux Socket API Connect 函数详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 问题: 将N个元素使用push_back
- 下一篇: 《Linux网络接口》---------