非阻塞connect套接字的作用:
1)完成乙個connect要花費rtt時間,而rtt波動範圍很大,從區域網上的幾個毫秒甚至是廣域網上的幾秒,這段時間也許有我們要執行的其他處理工作可以執行。
2)可以使用這個技術同事建立多個連線。
3)許多connect的超時實現以75秒為預設值,如果應用程式想自定義乙個超時時間,就是使用非阻塞的connect.
在乙個非阻塞的套接字上呼叫connect,connect會立即返回einprogress,錯誤,但是已經發起的tcp三次握手繼續進行。
非阻塞connect套接字實現時需要注意的細節:
1)連線到同一主機上,connect會立即完成,我們必須處理這種情形
2)posix關於select和非阻塞connect的以下兩個規則:
1)連線成功,描述符會變成可寫
2)連線建立遇到錯誤時,描述符變為可讀可寫。
非阻塞connect實現流程:
一: 1)呼叫fcntl把套接字設定為非阻塞
2)呼叫connect,如果返回0,表示連線已經完成,如果返回-1,那麼期望收到的錯誤是einprogress,連線建立已經 啟動,但是尚未完成。
二:呼叫select,等待套接字變為可讀可寫,
三:處理超時:
如果select返回0,超時發生,那麼返回etimeout錯誤給呼叫者,並且關閉套接字,防止已經啟動的三路握手繼續下去。
四:檢查可讀或可寫條件:
如果描述符變為可讀或可寫,我們就呼叫getsockopt獲取套接字的待處理錯誤(so_error套接字選項)
連線成功: getsockopt返回0
連線失敗:getsockopt返回0, 並且獲取相應的錯誤。
五: 恢復socket套接字狀態,如果getsockopt返回的錯誤是非0,那麼就設定errno為相應的值,函式返回-1,如果成功,就返回0
int connect_nonb(int sockfd, sockaddr* addr, socklen_t len, int nsec, int usec)
if(fcntl(sockfd, f_setfl, o_nonblock) < 0)
//connect
if(connect(sockfd, addr, len) < 0)
else
//select
fd_zero(&rset);
fd_set(sockfd, &rset);
wset = rset;
tv.tv_sec = nsec;
tv.tv_usec = usec;
if(select(sockfd + 1, &rset, &wset, null, nsec ? &tv : null) == 0)
//check read fd set and
write fd set
if(fd_isset(sockfd, &rset) || fd_isset(sockfd, &wset))
}if(error != 0)
if(fcntl(sockfd, f_setfl, flags) < 0)
return
0;}
套接字中connect阻塞與非阻塞問題
1 intpascal far connect socket s,conststructsockaddr far name,intnamelen 1 如果伺服器端程式已經執行,客戶端執行connect 函式,正常沒問題,2 如果服務端程式沒有執行的時候,客戶端執行connect 函式,會在此函式停留...
43 TCP套接字之connect非阻塞
本節來將客戶端的connect阻塞式改為非阻塞式.這樣可以同時向服務端發起多個連線並一起進行處理,非阻塞connect一般用來測試服務端的抗壓能力.connect設定為非阻塞之後會立即返回 設定errno為einprogress錯誤,表示連線操作正在進行中,但是仍未完成連線 同時tcp的三次握手操作...
非阻塞套接字
建立socket服務端 server socket.socket 設定非阻塞 server.setblocking false 繫結ip和埠 server.bind 6969 監聽 server.listen 5 存放連線進來的客戶端 client list accept 和recv 方法,設定非阻...