-
1 # 喲喲吼說科技
-
2 # ksfzhaohui
Socket的傳輸效率不同的I/O模型效率千差萬別,首先介紹一下unix的5種I/O模型,分別是:
1.阻塞I/O
在程序空間中呼叫recvfrom,其系統呼叫直到資料包到達且被複制到應用程式的緩衝區或者發生錯誤才返回,在此期間程序 進入睡眠或者掛起狀態。(程序掛起了)
2.非阻塞I/O
非阻塞I/O模型:recvfrom從應用層到核心的時候,如果該緩衝區沒有資料的話,就直接返回一個ewouldblock錯誤,使用者程序便在成功返回資料之前一直在呼叫recv操作詢問資料可讀性,輪詢的操作方式。(輪詢佔用CPU)
3.I/O複用
I/O複用(select,poll,epoll等支援I/O多路複用):程序透過將一個或多個連線傳遞給select或poll系統呼叫,I/O複用實現了多個連線或者多種連線(TCP,UDP等)共用了同一種等待機制,select會返回某個連線的可讀條件,呼叫recv/recvfrom把所讀的資料報複製到應用程序的緩衝區中。(多個連線註冊同一個select,nio是基於I/O複用模型實現的)
4.訊號驅動I/O
透過sigaction系統呼叫實現了SIGIO訊號的捕獲與處理函式,它是非阻塞的。當有資料準備就緒時,就為該程序生成一個SIGIO訊號,透過訊號回撥通知應用程式呼叫recvfrom來讀取資料。(捕獲核心傳送過來的訊號)
5.非同步I/O
非同步I/O:告知核心啟動某個操作,並讓核心在整個操作完成後通知我們,包括將資料從核心複製到使用者空間(非同步的)。
前面四種情況都是同步的,最後一種是非同步;已java為例對應的api有ServerSocket,ServerSocketChannel,AsynchronousServerSocketChannel;
我覺得可以從以下幾個方面著手:
1.選擇合適的I/O模型
2.執行緒模型
3.高效的協議
1.選擇合適的I/O模型
如上介紹的五種I/O模型,不同的I/O模型效率千差萬別;比如早期的網路連線使用阻塞的方式,然後每個請求對應一個執行緒的方式,到現在普遍使用的多路複用模式,使用很小的執行緒可以處理大量的連線
2.執行緒模型
有對應的單執行緒模型,多執行緒模型,主從執行緒模型;主從執行緒模型現在在很多通訊框架中普遍使用,大致就是連線的建立和讀寫分成多個執行緒池來處理;
3.高效的協議
既然是基於socket傳輸資料,那必然需要在其基礎上設計合適的協議,比如說我們常用的協議格式如下:
協議{協議頭(header)協議資料(data)}另外在協議的基礎上我們往往需要對資料進行序列化處理,不同的序列化方式效能上也差距很大,比如protobuf在效能上和資料量上都有優秀;當然往往也需要用到壓縮格式,不同的壓縮方法效能上也差距很大;
總結
本文從三個方面介紹瞭如何提高socket的傳輸效率;當然除了以上說的幾種情況,也和一些外部環境的配置有關,比如伺服器的連線數設定,網路頻寬等等
-
3 # 勇往直前的楓葉iT
服務端accept後,會單獨開啟一個執行緒來send和receive吧。連線量很大的情況下,io多路複用是首選,epoll就是典型。對於io密集型任務,非同步io表現優異,典型如node.js
回覆列表
socket俗稱套接字,用來描述IP地址和埠,常在網路通訊建立連線時使用。
如題,哪些方法可以提高socket的傳輸效率?
喲喲認為有三方面可以提升傳輸效率:
1、網路方面;
2、伺服器方面;
3、程式方面;
下面喲喲來簡單介紹一下具體實現:
1、網路方面就網路方面來說,主機至伺服器端的鏈路穩定性、時延性特別重要,另外就是主機的頻寬是多大,若使用千兆頻寬的網速,那麼在建立多個連線後,可以在一定程度上提升socket的傳輸效率;
2、伺服器方面伺服器的限速和限連線數,在一定程度上會影響socket的傳輸效率,因此在伺服器方面提升連線使用者的上下行速率和連線數,可以在一定程度上提升socket的傳輸效率;
3、程式方面在程式設計方面,若較大的檔案用一個執行緒去傳輸就會出現很多問題,如:網路問題或主機故障造成通訊中斷,那麼檔案需要進行重新傳輸,嚴重影響傳輸效率。因此可以將檔案分割成資料模型,開啟多個執行緒,根據網路情況去調整每條執行緒傳輸資料的大小,實現斷點續傳的方式,提升socket傳輸效率;