非阻塞connect()和accept()服務器
一.select()函數
select()函數準備好讀的條件:
1>.套接口有數據可讀
2>.該鏈接的讀這一半關閉(也就是接收了FIN的TCP鏈接)。對這樣的套接口進行讀操做將不阻塞並返回0(也就是返回EOF)。
3>.該套接口是一個偵聽套接口且已完成的鏈接數不爲0。
4>.其上有一個套接口錯誤待處理,對這樣的套接口的讀操做將不阻塞並返回-1,並設置errno,能夠經過設置SO_ERROR選項調用getsockopt函數得到。異步
select()函數準備好寫的條件: 1>.套接口有可用於寫的空間。 2>.該鏈接的寫這一半關閉,對這樣的套接口進行寫操做將產生SIGPIPE信號。 3>.該套接口使用非阻塞的方式connect創建鏈接,而且鏈接已經異步創建,或則connect已經以失敗了結。 4>.其上有一個套接口錯誤待處理。
二.accept()函數socket
1.阻塞模式tcp
阻塞模式下調用accept()函數,並且沒有新鏈接時,進程會進入睡眠狀態。函數
2.非阻塞模式.net
非阻塞模式下調用accept()函數,並且沒有新鏈接時,將返回EWOULDBLOCK錯誤。線程
非阻塞模式select() + accept()日誌
sockfd = listen_tcp(); //socket()、bind()、listen()code
FD_SET(sockfd, rset);blog
while(1){
ret = select(sockfd + 1, rset, NULL, NULL, timeout); // 等待某個事件發生:或是新鏈接、或是數據、或是FIN、或是RST到達 if(select()返回TIMEOUT){ //select()超時 printf("日誌打印"); sleep(1); continue; } else if(FD_ISSET(sockfd,&rset)){ //判斷句柄是否可讀,返回真表明可讀,可讀表明有新鏈接。 connfd = accept(sockfd, ...); } else if(select()返回錯誤){ return -1; } pthread_create(thread_recv_data, connfd, ...); // 建立線程處理新鏈接. close();
}
三.connect()函數
1.阻塞模式
客戶端調用connect()函數將激發TCP的三路握手過程,但僅在鏈接創建成功或出錯時才返回。返回的錯誤可能有如下幾種狀況:
1>.若是TCP客戶端沒有接收到SYN分節的響應,則返回ETIMEDOUT,阻塞模式的超時時間在75秒(4.4BSD內核)到幾分鐘之間。 2>.若是對客戶的SYN的響應時RST,則代表該服務器主機在咱們指定的端口上沒有進程在等待與之鏈接(例如服務器進程也許沒有啓動),這稱爲硬錯,客
戶一接收到RST,立刻就返回錯誤ECONNREFUSED.
3>.若是某客戶發出的SYN在中間的路由器上引起了一個目的地不可達ICMP錯誤,屢次嘗試發送失敗後返回錯誤號爲EHOSTUNREACH或ENETUNREACH.
附加:產生RST的三種狀況,一是SYN到達某端口但此端口上沒有正在偵聽的服務器、二是TCP想取消一個已有鏈接、三是TCP接收了一個根本不存在的鏈接上的
分節。
2.非阻塞工做模式
調用connect()函數會馬上返回EINPROCESS錯誤,但TCP通訊的三路握手過程正在進行,因此可使用select函數來檢查這個鏈接是否創建成功。
源自Berkeley的實現有兩條與select函數和非阻塞相關的規則:
1>.當鏈接成功創建時,描述字變成可寫。
2>.當鏈接創建出錯時,描述字變成便可讀又可寫。getsockopt()函數的errno == 0表示只可寫。
非阻塞模式 select() + connect()
while(1){
ret = connect(); if(errno == EINPROCESS){ //此時TCP的三路握手繼續進行 select(...) //等待某個事件發生:或是新鏈接、或是超時 if(FD_ISSET(sockfd,&wset) ){ //判斷句柄可寫,不能表明創建鏈接成功。 getsockopt(...); if(errno == 0){ //創建鏈接成功 } } else if(select()返回TIMEOUT){ sleep(1); continue(); } } else if(ret == -1){ //Connect failed } pthread_create(thread_send_log, ...); //創建線程處理新鏈接 close();
}
https://blog.csdn.net/bobkentblog/article/details/50850724