socket使用非阻塞connect

2021-07-30 09:12:30 字數 901 閱讀 3841

在使用tcp的connect呼叫時,預設是使用阻塞方式,當伺服器當前不可用時,connect會等待(內部在重試?)直到超時時間到達,而這個超時時間是系統核心規定的,不能使用setsocketopt來設定。

在碰到伺服器不可用,上層邏輯進行重試時,如果超時時間過長,會產生卡死的感覺,使用者體驗也不佳,所以需要控制connect的超時時間。

參考網路上的資料,這裡使用select。實現方式是:將socket設定為非阻塞方式,使用select來輪詢socket,在select裡指定超時時間,根據socket來判斷連線狀態。最後恢復socket的阻塞方式。

**如下(linux):

int connect_with_timeout(int socket, const

struct sockaddr *address, socklen_t address_len, int

time_out)

else

else

if(res == 0

) else

if (res == 1

) }

else}}

fcntl(socket, f_setfl, old_flag);

return

ret;

}

::connect在非阻塞模式下會立即返回,如果沒有其他錯誤,返回值等於0。

當::connect不能立即建立連線時,會返回einprogress,表示正在連線的過程中,這時可以使用select去輪詢套介面,而select超時時間由引數指定 。

select返回值小於0,表明connect出錯;等於0,表明connect超時;等於1,並且套介面的狀態是可寫,則表明connect已經成功建立。

最後恢復socket的阻塞屬性。

參考:

TCP非阻塞accept和非阻塞connect

非阻塞accept 當乙個已完成的連線準備好被accept的時候,select會把監聽socket標記為可讀。因此,如果用select等待外來的連線時,應該不需要把監聽socket設定為非阻塞模式,因為如果select告訴我們連線已經就緒,accept就不應該被阻塞。不過這樣做的時候有乙個bug 當...

socket阻塞與非阻塞

何為阻塞?在以上過程中若連線還沒到來,那麼接受阻塞,程式執行到這裡不得不掛起,cpu轉而執行其他執行緒。在以上過程中若資料還沒準備好,請閱讀會一樣也會阻塞。阻塞式網路io的特點 多執行緒處理多個連線。每個執行緒擁有自己的棧空間並且占用一些cpu時間。每個執行緒遇到外部為準備好的時候,都會阻塞掉。阻塞...

轉阻塞socket和非阻塞socket

讀操作 對於阻塞的socket,當socket的接收緩衝區中沒有資料時,read呼叫會一直阻塞住,直到有資料到來才返 回。當socket緩衝區中的資料量小於期望讀取的資料量時,返回實際讀取的位元組數。當sockt的接收緩衝 區中的資料大於期望讀取的位元組數時,讀取期望讀取的位元組數,返回實際讀取的長...