在使用tcp的connect呼叫時,預設是使用阻塞方式,當伺服器當前不可用時,connect會等待(內部在重試?)直到超時時間到達,而這個超時時間是系統核心規定的,不能使用setsocketopt來設定。
在碰到伺服器不可用,上層邏輯進行重試時,如果超時時間過長,會產生卡死的感覺,使用者體驗也不佳,所以需要控制connect的超時時間。
參考網路上的資料,這裡使用select。實現方式是:將socket設定為非阻塞方式,使用select來輪詢socket,在select裡指定超時時間,根據socket來判斷連線狀態。最後恢復socket的阻塞方式。
**如下(linux):
int connect_with_timeout(int socket, conststruct 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的接收緩衝 區中的資料大於期望讀取的位元組數時,讀取期望讀取的位元組數,返回實際讀取的長...