Socket程式設計中,阻塞與非阻塞的區別

2021-07-05 21:26:52 字數 2215 閱讀 2486

阻塞:一般的i/o操作可以在新建的流中運用.在伺服器回應前它等待客戶端傳送乙個空白的行.當會話結束時,伺服器關閉流和客戶端socket.如果在佇列中沒有請示將會出現什麼情況呢?那個方法將會等待乙個的到來.這個行為叫阻塞.accept()方法將會阻塞伺服器執行緒直到乙個呼叫到來.當5個連線處理完閉之後,伺服器退出.任何的在佇列中的呼叫將會被取消.

非阻塞:非阻塞套接字是指執行此套接字的網路呼叫時,不管是否執行成功,都立即返回。比如呼叫recv()函式讀取網路緩衝區中資料,不管是否讀到資料都立即返回,而不會一直掛在此函式呼叫上。在實際windows網路通訊軟體開發中,非同步非阻塞套接字是用的最多的。平常所說的c/s(客戶端/伺服器)結構的軟體就是非同步非阻塞模式的。 

具體機制就是上面所說的,簡明扼要的來說可以打個比方:

你有數個同學來訪 <---> 有若干資料需要收取

你時不時的去門口看看,沒有看到你同學的話就回客廳等待,看到同學就接到客廳來 <---> 非阻塞模式,無論收到資料與否都返回

你一直在門口等著你同學,接到後才回客廳 <---> 阻塞模式,接收到資料後才返回

使用阻塞怎麼了?會帶來什麼後果?在什麼情況之下?對效能有影響麼?

套接字有兩種模式,阻塞模式與非阻塞模式。預設建立的為阻塞模式.

在blocking model 下:

套接字在io時阻塞應用程式,就是說控制權不會返回給應用程式,也就是說程式執行到此**時會卡住。分兩種情況,1.send函式時,只有把要傳送的資料下傳至tcp層,send這句**才繼續向下執行,此時可確認自己的資料已經在網路上傳輸了2.recv時,只有收到一定資料給應用程式緩衝區時,recv這行**才會向下執行。如果不想這樣做,可以使用多執行緒,或者選用其他網路io模型。一般在做伺服器程式時,不會使用阻塞套接字,效能低,資料吞吐率也不高。優點是此種模型編寫難度較低,可以用來做入門的學習之用。

非阻塞套接字,io會馬上返回.但在send時,如果socket緩衝區已滿,會返回錯誤,使用wsagetlasterror會得到錯誤碼為wsaewouldblock,意思是說在乙個非阻塞的套接字上,請求沒有完成。recv時如果socket緩衝區沒有可以讀的資料,也會返回wsaewouldblock.

socket 的模式大概分為這麼幾種:

1、阻塞式的,socket操作都需要將執行緒掛起,等待核心完成後才能返回。

如: 呼叫connect=>進入核心=>syn包=〉伺服器返回syn ack 包=〉connect返回。

=〉ack包發往伺服器。

但一般來說,阻塞和非阻塞對於recv來說意義更大。

當在阻塞式的socket上呼叫recv時,如果這時網路棧上沒有資料給你接收,那麼這時執行緒將

會掛起,直到有報文給你接收才返回。

這樣就造成你的應用程式在企圖接收資料時候,而網路棧上沒有資料的時候就會被鎖住。

有什麼辦法解決這個問題呢? 我們來介紹io

2、 io復用, 就是在企圖讀寫資料的時候先詢問下是否可讀寫,如果不能,可以去幹別的事情,不會造成死鎖。

但是假如我們有大量的連線需要去頻繁的查詢可讀寫狀態,每次查詢都會和核心互動。這樣會造成

效率低下。再介紹一種

3、 重疊io. 就是一次查詢多個socket的狀態。不用去來來回回的遍歷。

另外,在windows socket api 中還有一種訊息機制,就是把socket狀態通知到視窗。然後用訊息去處理。

對於重疊io, 在windows上還有完成埠模型,他和重疊埠相比,不但能捕捉到io事件, 而且核心已經替你完成了socket io, 比如read事件, 在核心通知你的時候,他已經幫你讀好資料了,並放在你指定的快取中(這裡是指在使用者態下,事先為每個socket分配的記憶體)。

為什麼有這麼多socket模式呢? 哪個更好呢?

為什麼有,我不知道,可能是出於需求吧,

說說哪個更好?

孤立的來說,其實沒有哪個更好? 只有哪個更適合你的應用應用環境。

如: 阻塞式的比較簡單,方便,穩定。適合比較簡單的客戶端程式。

io復用我認為它適合socketio操作比較少的情況。

重疊io就適合高效能的伺服器的開發,另外完成埠是windows上比較公認的高效能伺服器的網路開發模型。當然, windows 的iocp也有個壞處,就是需要大量的記憶體,應為前面說了他需要事先指定快取。不過高效能的 伺服器,一般都不用windows平台。

windows的訊息模型就比較適合有ui的應用程式。

當然, 有些模型的選擇上可能還有個人愛好的因素,

如, 我可能不喜歡用訊息模型,

我不喜歡被動的被通知, 而喜歡主動的去查詢。

socket阻塞與非阻塞

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

Socket程式設計中,阻塞與非阻塞的區別

阻塞 一般的i o操作可以在新建的流中運用.在伺服器回應前它等待客戶端傳送乙個空白的行.當會話結束時,伺服器關閉流和客戶端socket.如果在佇列中沒有請示將會出現什麼情況呢?那個方法將會等待乙個的到來.這個行為叫阻塞.accept 方法將會阻塞伺服器執行緒直到乙個呼叫到來.當5個連線處理完閉之後,...

socket程式設計 阻塞和非阻塞

阻塞方式下,connect首先傳送syn請求道伺服器,當客戶端收到伺服器返回的syn的確認時,則connect返回.否則的話一直阻塞.非阻塞方式,connect將啟用tcp協議的三次握手,但是connect函式並不等待連線建立好才返回,而是立即返回。返回的錯誤碼為einprogress,表示正在進行...