accept()函數?
? ? ? ?系統調用 accept() 會有點古怪的地方的!
? ? ? ?你能夠想象發生 這種事情:有人從非常遠的地方通過一個你在偵聽 (listen()) 的port連接 (connect()) 到你的機器。它的連接將增加到等待接受 (accept()) 的隊列 中。
? ? ? ?你調用 accept() 告訴它你有空暇的連接。它將返回一個新的套接字文 件描寫敘述符!這樣你就有兩個套接字了,原來的一個還在偵聽你的那個port, 新的在準備發送 (send()) 和接收 ( recv()) 數據。這就是這個過程!?
? ? ? ?函數是這樣定義的:?
#include <sys/socket.h> int accept(int sockfd, void *addr, int *addrlen);
? ? ? ?sockfd 相當簡單,是和 listen() 中一樣的套接字描寫敘述符。
? ? ? ?addr 是個指向局部的數據結構 sockaddr_in 的指針。這是要求接入的信息所要去的地 方(你能夠測定那個地址在那個port呼叫你)。
? ? ? ?在它的地址傳遞給 accept 之 前,addrlen 是個局部的整形變量,設置為 sizeof(struct sockaddr_in)。??accept 將不會將多余的字節給 addr。假設你放入的少些,那么它會通過改變 addrlen 的值反映出來。?
? ? ? ?在錯誤時返回-1,并設置全局錯誤變量 errno。
? ? ? ? 如今是你應該熟悉的代碼片段。?
#include <string.h> #include <sys/socket.h> #include <sys/types.h> #define MYPORT 3490 /*用戶接入端口*/ #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); /* 錯誤檢查*/ 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);
? ? ? ? 注意,在系統調用 send() 和 recv() 中你應該使用新的套接字描寫敘述符 new_fd。假設你僅僅想讓一個連接進來,那么你能夠使用 close() 去關閉原 來的文件描寫敘述符 sockfd 來避免同一個port很多其它的連接。
? ? ? ? 當你第一次調用 socket() 建立套接口描寫敘述符的時候,內核就將他設置為堵塞。假設你不想套接口堵塞,你就要調用函數 fcntl():
? ? ? ? 通過設置套接口為非堵塞,你可以有效地"詢問"套接口以獲得信息,可是一般來說輪詢不是一個好主意,會浪費cpu時間,
? ? ? ? 更好的方法是用 select()方法 去查詢是否有數據要讀進來
? ? ? ? select()--多路同步 I/O
? ? ? ? select() 讓你能夠同一時候監視多個套接口。假設你想知道的話,那么他就會告訴你哪個套接口準備讀,哪個又準備好了寫,哪個套接口又發生了例外 (exception)。
? ? ? ? int select(int numfds, fd_set *readfds, fd_set *writefds,?fd_set *exceptfds, struct timeval *timeout);
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
