accept()函數(shù)?
? ? ? ?系統(tǒng)調(diào)用 accept() 會(huì)有點(diǎn)古怪的地方的!
? ? ? ?你能夠想象發(fā)生 這種事情:有人從非常遠(yuǎn)的地方通過(guò)一個(gè)你在偵聽(tīng) (listen()) 的port連接 (connect()) 到你的機(jī)器。它的連接將增加到等待接受 (accept()) 的隊(duì)列 中。
? ? ? ?你調(diào)用 accept() 告訴它你有空暇的連接。它將返回一個(gè)新的套接字文 件描寫(xiě)敘述符!這樣你就有兩個(gè)套接字了,原來(lái)的一個(gè)還在偵聽(tīng)你的那個(gè)port, 新的在準(zhǔn)備發(fā)送 (send()) 和接收 ( recv()) 數(shù)據(jù)。這就是這個(gè)過(guò)程!?
? ? ? ?函數(shù)是這樣定義的:?
#include <sys/socket.h>
int accept(int sockfd, void *addr, int *addrlen);
? ? ? ?sockfd 相當(dāng)簡(jiǎn)單,是和 listen() 中一樣的套接字描寫(xiě)敘述符。
? ? ? ?addr 是個(gè)指向局部的數(shù)據(jù)結(jié)構(gòu) sockaddr_in 的指針。這是要求接入的信息所要去的地 方(你能夠測(cè)定那個(gè)地址在那個(gè)port呼叫你)。
? ? ? ?在它的地址傳遞給 accept 之 前,addrlen 是個(gè)局部的整形變量,設(shè)置為 sizeof(struct sockaddr_in)。??accept 將不會(huì)將多余的字節(jié)給 addr。假設(shè)你放入的少些,那么它會(huì)通過(guò)改變 addrlen 的值反映出來(lái)。?
? ? ? ?在錯(cuò)誤時(shí)返回-1,并設(shè)置全局錯(cuò)誤變量 errno。
? ? ? ? 如今是你應(yīng)該熟悉的代碼片段。?
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#define MYPORT 3490 /*用戶(hù)接入端口*/
#define BACKLOG 10 /* 多少等待連接控制*/
main()
{
int sockfd, new_fd; /* listen on sock_fd, new connection on new_fd */
struct sockaddr_in my_addr; /* 地址信息 */
struct sockaddr_in their_addr; /* connector's address information */
int sin_size;
sockfd = socket(AF_INET, SOCK_STREAM, 0); /* 錯(cuò)誤檢查*/
my_addr.sin_family = AF_INET; /* host byte order */
my_addr.sin_port = htons(MYPORT); /* short, network byte order */
my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
bzero(&(my_addr.sin_zero),; /* zero the rest of the struct */
/* don't forget your error checking for these calls: */
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
listen(sockfd, BACKLOG);
sin_size = sizeof(struct sockaddr_in);
new_fd = accept(sockfd, &their_addr, &sin_size);
? ? ? ? 注意,在系統(tǒng)調(diào)用 send() 和 recv() 中你應(yīng)該使用新的套接字描寫(xiě)敘述符 new_fd。假設(shè)你僅僅想讓一個(gè)連接進(jìn)來(lái),那么你能夠使用 close() 去關(guān)閉原 來(lái)的文件描寫(xiě)敘述符 sockfd 來(lái)避免同一個(gè)port很多其它的連接。
? ? ? ? 當(dāng)你第一次調(diào)用 socket() 建立套接口描寫(xiě)敘述符的時(shí)候,內(nèi)核就將他設(shè)置為堵塞。假設(shè)你不想套接口堵塞,你就要調(diào)用函數(shù) fcntl():
? ? ? ? 通過(guò)設(shè)置套接口為非堵塞,你可以有效地"詢(xún)問(wèn)"套接口以獲得信息,可是一般來(lái)說(shuō)輪詢(xún)不是一個(gè)好主意,會(huì)浪費(fèi)cpu時(shí)間,
? ? ? ? 更好的方法是用 select()方法 去查詢(xún)是否有數(shù)據(jù)要讀進(jìn)來(lái)
? ? ? ? select()--多路同步 I/O
? ? ? ? select() 讓你能夠同一時(shí)候監(jiān)視多個(gè)套接口。假設(shè)你想知道的話(huà),那么他就會(huì)告訴你哪個(gè)套接口準(zhǔn)備讀,哪個(gè)又準(zhǔn)備好了寫(xiě),哪個(gè)套接口又發(fā)生了例外 (exception)。
? ? ? ? int select(int numfds, fd_set *readfds, fd_set *writefds,?fd_set *exceptfds, struct timeval *timeout);
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

