多個socket同時發送數據,網卡是輪流發送每個socket數據包嗎?每個包多大?

如果建立多個了socket連接,同時都發送數據(同一個網卡),網卡驅動是按照什麼調度演算法來發送數據的?是輪流發包嗎?每個包多大?


在乙太網卡的眼裡,沒有socket的概念,從IP層輸送下來的IP包,是一塊塊數據塊,其中,有數據塊的起始地址、數據塊的長度等。

乙太網卡將數據塊copy到自己的發送空間,採用先進先出(FIFO)的調度機制,將一塊塊數據按序發送出去。乙太網卡,遵守一條原則,一個數據塊(IP包),生成一個以太幀。

這就好比銀行的排隊系統,先來先服務,對於普通用戶來說,為了獲得先服務,必須先到。

但銀行又把用戶分為普通用戶、金卡、白金卡用戶,搞三條隊伍,分別對應三種用戶,不用說,白金卡用戶獲得最優先服務權。

同理,可以使用ToS將不同的應用IP包設置成不同優先順序,IP包發給網卡,網卡把不同優先順序的IP包放入不同的排隊系統(Queue),至於每個隊伍能獲得多少服務時間,可以通過配置實現,比如下面要介紹到的WFQ。

這些排隊系統的名稱有:
加權公平隊列(WFQ)
基於類的加權公平隊列(Class-Based WFQ)
低延遲隊列(LLQ)

其中LLQ只服務VIP客戶(通常為語音流量),只要該隊伍有客戶,其它隊伍的客戶必須等該客戶服務完,才能得到服務。這樣就可以讓VIP客戶得到最快的服務。


這個是一個qos的問題


關於乙太網卡驅動程序如何對待網卡緩存中的數據,請看 @車小胖 大牛的回答。我側重應用開發,對驅動了解的不是很深入,有興趣的同學也可以去看看《Linux驅動程序開發 3rd》有免費的電子版。

---------------------------------------------------------------

這個坑真的挺大,最近也忙,加上我比較懶,又喜歡旁徵博引裝逼,所以坑會填的慢一些。

我就先給大家推薦幾本書吧。注意排名分先後,由淺入深,注意力度,哈哈。

1、圖解tcp/ip 5th

2、TCP-IP詳解卷一:協議

如果c基礎好,建議看

3、TCP-IP詳解卷二:實現

否則,看

3、UNIX網路編程卷1:套接字聯網API 3rd

----------------------------------------------------------------

網卡根本不知道幀、packet、datagram、消息這些東東,他也不知道乙太網協議,IP,TCP,SOCKET,HTTP,這些東西!
網卡有一塊數據緩衝區,他給操作系統提供一個io埠,操作系統大概使用一種類似這種命令Output 1024Byte to 網卡埠,來寫數據到網卡緩衝區!
網卡里的硬體邏輯大概就是一個while循環:
While(緩衝區不空)
發送數據!
一次發送的是bit,不考慮網路狀況,,速率可參考筆記本網卡信息10M 100M 1000M,,都有!

這是一個挺大的問題,我先列一下提綱,回去添坑!

1-網卡的數據如何被讀入操作系統

2-位元組流在協議棧如何轉換,最後得到你所需的報文

3-這個過程進程是一個什麼樣的存在

手機碼字真麻煩!


這個問題從軟體層面貫穿了用戶態,內核態,網卡驅動,網卡這條線,戰線太長比較難回答,只能嘗試回答一下。從內核的角度來說,dev_queue_xmit或net_tx_action調用網卡驅動提供的hard_start_xmit函數的過程中,完成了從內核到網卡驅動buffer的frame移動,在這個中間的Traffic Control應該是將傳輸隊列里的數據重新整形的最後機會。如下圖,是Understanding Linux Network Internals中的圖,看右邊的部分,說明了這個過程。

問題本身關心的是並發。在調用驅動提供的dev-&>hard_start_xmit時,返回值可能會是NETDEV_TX_LOCKED,說明其他CPU正在佔有這個網卡driver的鎖,此時傳輸的數據會重新放回到queue裡面等著軟中斷來的時候繼續嘗試傳輸。

再回頭來看看問題中的socket, socket是提供給用戶態程序的系統調用,如果有多個用戶態線程同時往多個fd裡面寫數據,假設只有一個core的情況, 內核會將多個ready to run的線程依次調度到這個core上去跑,從時序上還是分時的,對於網卡來說還算不上並發。如果有多個core, 內核在調度時可以把多個ready to run的線程同時調度到不同的core上運行,才有更大機會出現CPU搶佔網卡driver鎖的競爭。


不專業的回答:

socket和網卡按照ISO模型隔了網路層,網卡還工作在數據鏈路層和物理層

網路層和數據鏈路層都有各種QoS和調度演算法,都會影響發送順序

包大小不超過MTU大小


這問題可以轉換為:

「多個進程同時開始以 0000 填充內存,CPU是按照什麼調度演算法來填充的?輪流填充么?每次填充多大?」


推薦閱讀:

TAG:計算機網路 | 驅動程序 | Linux內核 |