非阻塞 connect套接字

2021-07-11 14:12:15 字數 1593 閱讀 7279

非阻塞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 方法,設定非阻...