linux應用層呼叫了send傳送網路資料,那麼按照簡單的思維,這個動作會觸發網絡卡傳送資料,而現實並不是如此!
首先對於send來說,分為阻塞傳送和非阻塞傳送:
(1)阻塞操作
核心會檢測傳送緩衝區是否存在足夠的空間存放使用者資料,如果空間足夠那麼直接拷貝資料到socket send buffer,後續傳送動作交給協議棧來支援;如果空間不夠那麼send操作會阻塞,直到核心傳送緩衝區空間足夠,再把資料拷貝到傳送緩衝區,並最後返回使用者空間。
(2)非阻塞操作
對於非阻塞操作來說,當傳送緩衝區空間不夠時send不會阻塞,而是直接返回-1,errno設定為eagain。
以上可知,send僅僅保證了資料存放到了傳送緩衝區,而不能保證一定從網絡卡發出去,因此在socket這一層,傳送就已經變為了非同步的操作了。
對於tcp協議來說,阻塞操作是在如下的函式中實現的:
現在我還有另外乙個問題,既然send函式並不一定保證資料從網絡卡出去,那麼何時會執行網絡卡傳送動作呢?這個問題在後面乙個章節做介紹。int
tcp_sendmsg
(struct kiocb *iocb,
struct sock *sk,
struct msghdr *msg,
size_t size)
如果socket傳送緩衝區中空間足夠大,send拷貝資料到核心傳送緩衝區中,那麼實際傳送動作是什麼時候發生的呢?
實際上send函式並不是僅僅拷貝資料,它會判斷緩衝區中的資料量以及當前的協議棧狀態,當符合傳送條件時就會在send中觸發實際的傳送動作。
主要的邏輯還是在tcp_sendmsg函式中,我檢視了對應的**,總結了如下幾個傳送的地方,注意以下所有的傳送僅僅是指資料經過協議棧發出,並不代表資料已經被acked:
情況1:
發現傳送的資料量已經超過傳送視窗的一半時,設定tcp_nagle_push標記,會忽略nagle規則強制傳送緩衝區中的所有skb。
情況2:
如果當前skb是未傳送skb鍊錶的header,那麼它肯定會被傳送,設定tcp_nagle_push標記,會忽略nagle規則強制傳送當前的這乙個skb,注意僅僅傳送乙個。
情況3:
如果傳送緩衝區已經滿了,需要觸發立即傳送,騰出記憶體空間,設定了tcp_nagle_push標記,表示忽略nagle規則強制傳送緩衝區中的所有skb。
情況4:
當send把一次應用寫入的資料都已經寫入到傳送緩衝區後,退出函式之前,會呼叫一次傳送函式,注意這次傳送是需要按照nagle規則判斷是否觸發真實傳送的,如果滿足nagle條件才會傳送,否則依然會保留在傳送緩衝區中。
nagle
上面介紹了幾種可能在send中觸發傳送的條件,那麼其中有一類是需要經過nagle規則判斷的,那麼到底什麼樣的情況是滿足nagle規則的呢?
關於nagle演算法,為了優化小資料報的傳送次數,可以累積上層下發的小資料報到一定的程度,再進行組包傳送,對於傳送端來說,它的傳送時機有如下幾個:
這裡想到乙個問題,假如一直傳送小包,按照nagle演算法,實際傳送函式結束並不會把小包傳送出去,而是等待小包合併為大包後才傳送,那麼假如一直沒有小包過來合併,那麼按照上述規則,這個小包是不是永遠都不傳送了呢?實際上並不是的,而是在tcp接收處理時會做處理,可以看上面的第二個規則:1.乙個包是大於等於mss長度
2.所有傳送包都已經被確認
3.包含有fin的包
4.包含tcp_nodelay標記
當所有傳送包都已經被確認時,即使當前傳送緩衝區中存在小包,那麼也不繼續等待了,而是直接傳送出去。另外如果一直沒有接收到ack,當時間超時也會觸發傳送動作。
linux source code:linux-3.10.108
網路資料報傳送工具PacketSender中文原始碼
在網上發現了乙個好用的工具packetsender,資料報傳送器。對於寫網路程式來說,有很大的便利性。雖然在linux下,netcat工具也很好用,但是這個也不錯。原本是英文的,給翻譯了一下。這是基於qt開發的。有一些翻譯不對的地方,還請指正。本文由烏合之眾 lym瞎編,歡迎 blog.cnblog...
網路資料報傳送接收全過程
linux的網路介面分為四部分 網路裝置介面,網路介面核心,網路協議族,網路介面socket層。可參考 網路裝置介面部分主要負責從物理介質接收和傳送資料,實現的檔案在linu driver net目錄下面。網路介面核心部分是整個網路介面的關鍵部位,它為網路協議提供統一的傳送介面,遮蔽各種各樣的物理介...
網路資料報傳送接收全過程
linux的網路介面分為四部分 網路裝置介面,網路介面核心,網路協議族,網路介面socket層。可參考 應用程式呼叫系統呼叫,將資料傳送給socket socket檢查資料型別,呼叫相應的send函式 send函式檢查socket狀態 協議型別,傳給傳輸層 tcp udp 傳輸層協議 為這些資料建立...