【2018.08.13 C與C++基礎】網絡通信:阻塞與非阻塞socket的基本概念及簡單實現


一、前言

最近在做Matalb/Simulink與C/C++的混合編程,主要是完成TCP、UDP、SerialPort等常見通信方式的中間件設計,為Simulink模型提供數據采集及解析模塊。

問題在於沒有搞清楚Simulink中調用C/C++的內在機制,將測試OK的C++程序移植到mex上時,總會出現很多問題,比如通信的阻塞與非阻塞,有時候自己寫半天可能在性能上並不比Matalb內置模塊好,所以搞清楚一些原理性的東西還是很有必要的。

參考資料:

1. 阻塞與非阻塞socket的優缺點 https://blog.csdn.net/taotaoah/article/details/52441517

2. 創建TCP/IP客戶端對象以通過TCP/IP進行通信 https://ww2.mathworks.cn/help/matlab/ref/tcpclient.html

3. 阻塞與非阻塞socket的優缺點 http://www.cnblogs.com/sunada2005/p/3591378.html

4. tcp socket阻塞與非阻塞 https://blog.csdn.net/xdshengk/article/details/51066959

5. 從linux源碼看socket的阻塞和非阻塞 https://blog.csdn.net/u011418530/article/details/79875707

二、基本概念

簡單轉載一點上述文章中對阻塞與非阻塞的優缺點對比,其實應該是根據實際情況來選擇,但沒搞明白Matlab及Simulink中的TCPClient到底是阻塞還是非阻塞的實現。

所謂阻塞方式的意思是指,當試圖對該文件描述符進行讀寫時,如果當時沒有東西可讀,或者暫時不可寫,程序就進入等待狀態,直到有東西可讀或者可寫為止。

而對於非阻塞狀態,如果沒有東西可讀,或者不可寫,讀寫函數馬上返回,而不會等待(這也與設置的超時時間有關)。

非阻塞,就是進程或線程執行此函數時不必非要等待事件的發生,一旦執行肯定返回,以返回值的不同來反映函數的執行情況,如果事件發生則與阻塞方式相同,若事件沒有發生則返回一個代碼來告知事件未發生,而進程或線程繼續執行,所以效率較高;

簡單的講,阻塞就是GET,非阻塞就是PUT;

阻塞好控制,不發送完數據程序不會走下去,但是對性能有影響。

非阻塞不太好控制,可能和能力有關,但是性能會得到很大提升。

阻塞式的編程方便,非阻塞的編程不方便,需要程序員處理各種返回;

阻塞處理簡單,非阻塞處理復雜;

阻塞效率低,非阻塞效率高;

阻塞模式,常見的通信模型為多線程模型,服務端accept之后,對每個socket創建一個線程去recv。

邏輯上簡單,適用於並發量小(客戶端數目少),連續傳輸大數據量的情況下,比如文件服務器。

還有就是在客戶端recv服務器消息的時候也經常用,因為客戶端就一個socket,用阻塞模式不影響效率,而且編程邏輯上要簡單得多。

非阻塞模式,常見的通信模型為select模型和IOCP模型,適用於高並發,數據量小的情況,比如聊天室;

客戶端多的情況下,如果采用阻塞模式,需要開很多線程,影響效率;

另外,客戶端一般不采用非阻塞模式。

未完待續....


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM