接字的非阻塞模式是指套接字在執行操作時,呼叫的函式不管操作是否完成都會立即返回的工作模式。非阻塞套接字在處理同時建立的多個連線,傳送和接收的資料量不均,時間不定等方面具有明顯的優勢。但這種套接字在使用上存在一定難度。本章講述套接字的非阻塞模式及其乙個遠端算數運算套接字程式。
所有windows
平台都支援套接字以阻塞模式和非阻塞模式的方式工作。
把套接字設定為非阻塞模式,即通知系統核心:在呼叫windowssocketsapi
時,不要讓執行緒隨眠,而應該讓函式理解返回。在返回時,該函式返回乙個錯誤**。乙個非阻塞模式套接字多次呼叫
recv()
的過程如上。前
3次呼叫
recv()
函式時,核心函式還沒有準備好。因此,該函式理解返回
wsaewouldblock
錯誤**。第
4次呼叫
recv()
函式時,資料已經準備好,被負責到應用程式的緩衝區中,
recv()
返回成功指示,應用程式開始處理資料。
當使用socket(),wsasocket()
建立套接字時,預設都是阻塞的。在建立套接字之後,通過呼叫
ioctlsocket()
,將該套接字設定為非阻塞模式。
套接字設定為非阻塞模式後,在呼叫windowssocketsapi
函式時,呼叫函式會立即返回。大多數情況下,這些函式呼叫都會呼叫「失敗」,並返回
wsaewouldblock
錯誤**。說明請求的操作在呼叫期間內沒有時間完成。通常,應用程式需要重複呼叫該函式,直到獲得成功返回**。
wsaewouldblock的含義
函式名說明accept(),wsaacept()
應用程式沒有接收到連線請求
recv(),wsarecv(),recvfrom(),wsarecvfrom()
接收緩衝區沒有收到資料
send(),wsasend(),sendto(),wsasendto()
傳送緩衝區此時不可用
connect(),wsaconnect()
連線未能立即完成
closesocket()
通常情況下意味著應用程式使用so_linger
選項並且設定乙個非零的超時值,呼叫了
setsocketopt()
需要說明的是並非所有的windowssocketsapi
在非阻塞模式下呼叫,都會返回
wsewouldblock
錯誤。eg:bind(),listen()。
要將套接字設定為非阻塞模式,除了使用ioctlsocket()
函式之外,還可以使用
wsaasyncselect()(第7
章講解)
,wsaeventselect()(第8
章講解)
。當呼叫該函式時,套接字會自動地設定為非阻塞方式。
由於使用非阻塞套接字在呼叫函式時,會經常返回wsaewouldblock
錯誤。所以在任何時候,都應仔細檢查返回**,並做好應對「失敗」的準備。應用程式連續不斷的呼叫這個函式,直到它返回成功指示為止。本章程式清單中,在
while
迴圈體內不斷的呼叫
recv(),
以讀入1024
個位元組的資料。這種做法很浪費系統資源。
有人使用msg_peek
標誌呼叫
recv()
檢視緩衝區中是否有資料可讀。同樣,這種方法也不好,因為該做法對系統造成的開銷是很大的,並且應用程式至少要呼叫
recv()
兩次,才能實際地讀入資料。較好的做法是,使用套接字的「
i/o模型」(第
6,7,8,9,10
章來講解
)來判斷非阻塞套接字是否可讀可寫。
非阻塞模式套接字與阻塞套接字相比,使用較複雜。使用非阻塞模式套接字,需要編寫更多的**,以便在每個windowssocketapi
函式呼叫中,對收到的
wsaewouldblock
錯誤進行處理。因此,非阻塞套接字便顯得有些難於使用。
但是,非阻塞套接字在控制建立的多個連線,在資料的收發量不均,時間不定等方面,明顯具有優勢。通常情況下,可考慮使用套接字的「i/o
模型」,它有助於應用程式通過非同步方法,同時對乙個或多個套接字的通訊加以管理。
阻塞模式和非阻塞模式
好文得轉 何為阻塞?在以上過程中若連線還沒到來,那麼 accept 會阻塞 程式執行到這裡不得不掛起,cpu 轉而執行其他執行緒。在以上過程中若資料還沒準備好,read 會一樣也會阻塞。阻塞式網路 io 的特點 多執行緒處理多個連線。每個執行緒擁有自己的棧空間並且占用一些 cpu 時間。每個執行緒遇...
非阻塞模式
非阻塞模式是指利用socket事件的訊息機制,server端與client端之間的通訊處於非同步狀態。在非阻塞模式下利用socket事件的訊息機制,server端與client端之間的通訊處於非同步狀態下。通常需要從csocket類派生乙個新類,派生新類的目的是過載socket事件的訊息函式,然後在...
Socket 阻塞模式和非阻塞模式
阻塞i o模型 簡介 程序會 一直阻塞 直到資料拷貝 完成 應用程式呼叫乙個io函式,導致應用程式阻塞,等待資料準備好。如果資料沒有準備好,一直等待 資料準備好了,從核心拷貝到使用者空間,io函式返回成功指示。阻塞i o模型圖 在呼叫recv recvfrom 函式時,發生在核心中等待資料和複製資料...