標籤:socket 伺服器 緩衝區 linux 用戶端
阻塞:顧名思義,就是指在執行裝置操作時若不能獲得資源則掛起操作,直到滿足可操作的條件後再進行操作,被掛起的進程進入休眠狀態,被從調度器的運行隊列移走,直到等待的條件滿足。
非阻塞:就是反過來,進程在不能進行裝置操作時並不掛起,它或者放棄,或者不停的查詢,直到可以進行位置。
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/6D/CD/wKioL1VsKMKRPNOEAAFrmAaak10486.jpg" title="1b.jpg" alt="wKioL1VsKMKRPNOEAAFrmAaak10486.jpg" />
Socket編程中,阻塞與非阻塞的區別:
阻塞:一般的I/O操作可以在建立的流中運用.在伺服器回應前它等待用戶端發送一個空白的行.當會話結束時,伺服器關閉流和用戶端socket. 如果在隊列中沒有請示將會出現什麼情況呢?那個方法將會等待一個的到來.這個行為叫阻塞.accept()方法將會阻塞伺服器線程直到一個呼叫到來.當5個串連處理完閉之後,伺服器退出.任何的在隊列中的呼叫將會被取消.
非阻塞:非阻塞通訊端是指執行此通訊端的網路調用時,不管是否執行成功,都立即返回。比如調用recv()函數讀取網路緩衝區中資料,不管是否讀到資料都立即返回,而不會一直掛在此函數調用上。在實際Windows網路通訊軟體開發中,非同步非阻塞通訊端是用的最多的。平常所說的C/S(用戶端/伺服器)結構的軟體就是非同步非阻塞模式的。
具體機制就是上面所說的,簡明扼要的來說可以打個比方:
你有數個同學來訪 <---> 有若干資料需要收取
(1)你時不時的去門口看看,沒有看到你同學的話就回客廳等待,看到同學就接到客廳來 <---> 非阻塞模式,無論收到 資料與否都返回
(2)你一直在門口等著你同學,接到後才回客廳 <---> 阻塞模式,接收到資料後才返回
使用阻塞怎麼了?會帶來什麼後果?在什麼情況之下?對效能有影響嗎?:
通訊端有兩種模式,阻塞模式與非阻塞模式。預設建立的為阻塞模式.
在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的應用程式。
Linux下阻塞與非阻塞IO