tcp ip stack 中的資料報佇列

2021-04-07 00:34:19 字數 1915 閱讀 5366

tcp/ip

是一種儲存

/**的協議,因此,在

stack

中必然存在資料報的佇列(

sk_buff queue

)。正是這些佇列,將

stack

的處理邏輯比較清晰的劃分成幾個部分。

資料報接收路徑上的佇列:

1、網路層佇列:

softnet_data[this_cpu]. input_pkt_queue 每個

cpu

有乙個這樣的佇列。此佇列將網絡卡驅動的處理邏輯與協議分析(網路層、傳輸層)的處理邏輯區分開來。

當網絡卡驅動處理資料的時候,工作在中斷上下文,它的處理結果就是將資料報盡快的送入此佇列。

而真正的網路層、傳輸層協議分析和處理邏輯是在

net_rx_action

軟中斷中完成的。

當net_rx_action

被cpu

排程後,從此佇列中接收資料報,進行網路層和傳輸層的協議分析和處理。

2、bsd socket

層佇列:

sock-> receive_queue 每個

struct socket

對應乙個這樣的佇列。此佇列將

net_rx_action

軟中斷與

socket

層的處理邏輯區分開來。

當net_rx_action

完成了網路層和傳輸層的處理後,需要將資料報送到對應的

struct socket

結構的此佇列中。

而應用層則通過

read

、recvfrom

等系統呼叫從此隊禮中取走資料。

資料報傳送路徑上的佇列:1、

bsd socket

層佇列:

sock->write_queue 當從

user space

呼叫write()

或sendto()

或sendmsg()

等系統呼叫傳送資料的時候,

tcp

和udp

的處理過程有所不同。

對於udp

來說,在這一層不需要通過佇列來緩衝資料。

sendto

或者sendmsg

將原始資料拆分成

sk_buff

結構,然後進行傳輸層、網路層處理,最後送到相應的

device

對應的輸出佇列。

但是tcp

是一種流協議,具有擁塞控制的功能,因此可能需要在這一層緩衝資料。這個佇列就是

struct socket

結構中的

write_queue。

為什麼說可能需要用到這個佇列了。因為write 或者sendmsg 在將原始資料拆分成sk_buff 結構後,就嘗試將這些資料報傳送出去並等待對端的ack。如果網路足夠流暢,那麼就不需要將資料緩衝在佇列中。如果網路比較繁忙,在設定時間內等不到ack,或者對端的tcp 視窗不允許接收資料,那麼就必須先緩衝到佇列中,留到合適的時機再發。(顯然會有乙個定時器來幹這個事情)。 2

、網路裝置的佇列:

dev->qdisc

每個網路裝置對應乙個此佇列(也可以沒有,例如

lo)。它將網路層與裝置驅動區分開來。

資料報在網路層處理完之後,可能會緩衝到此佇列中。

這裡也只是可能會緩衝,因為資料報被送到此佇列後,如果條件允許,立刻就被傳送出去。

此佇列是

linux

核心中實現

qos

的關鍵。不同的

qos

策略採用不同的方式對此佇列中的資料報進行處理,預設的方式是

fifo

。如果底層

driver

處理速度跟不上傳送資料報的速度,那麼當佇列滿了以後,後續的資料報就會被丟棄。

資料報在Linux中的流程

1.中斷處理函式中 網絡卡收到一幀 引發中斷 cpu呼叫相應的中斷處理函式 指向此網絡卡驅動中的相應的處理函式 把此packet讀到ram中 呼叫netif rx函式來打上timestamp,並把此skb放入到cpu設定的佇列中 標記軟中斷 cpu raise softirq 中斷完成。2 當軟中斷...

資料報在網路中的流轉

文分為兩部分 基礎概念介紹 和資料報在網路中流轉的過程 1.啥是集線器 從0開始,當一台機器a想與機器b發訊息,連一根實體線即可完成 假設這根線很牛逼,連上就能通資訊 兩台機器互動沒有問題,如果一台機器a想與b,c,d,e,f五颱機器通訊,他就需要扯五根線,如果六臺機器想互相通訊那就得扯十五條,十分...

資料報格式 USB資料報解析

由域構成的包有四種型別,分別是令牌包 資料報 握手包和特殊包,前面三種是重要的包,不同包的域結構不同,介紹如下 1 令牌包 分為輸入包 輸出包 設定包和幀起始包 注意這裡的輸入包是用於設定輸入命令的,輸出包是用來設定輸出命令的,而不是放資料的 其中輸入包 輸出包和設定包的格式都是一樣的 sync p...