記事ディレクトリ
ネットワークカードからプロトコルスタック境界までの処理:
データパケットの受け入れプロセス
データパケットの受信は、ネットワークカードドライバー、システムカーネルスペース、最後にユーザースペースのアプリケーションの3層で行われます。
次に、詳細を説明します。
- 新しいデータパケットが到着すると、データパケットをカーネルメモリ領域に配置することにより
NIC
(network interface controller
)が呼び出さDMA
engine
れRing
Buffer
ます。 - データパケットが正常に受信されると
NIC
、割り込みが開始され、カーネルの割り込みハンドラーがデータパケットをIP
レイヤーに渡します。 IP
レイヤー処理後、データパケットはキューに入れられ、TCP
レイヤー処理を待ちます。各データパケットはTCP
、レイヤー内の一連の複雑なステップを経て、TCP
ステートマシンを更新します。- 最終的に到着
recv
Buffer
し、アプリケーションによって受信および処理されるのを待っています。
いくつかの点を説明しましょう:
Linux
カーネルはsk_buff
(socket kernel buffers
)データ構造を使用してデータパケットを記述します。Ring Buffer
のサイズは固定されており、実際のデータパケットは含まれていませんが、指定されたsk_buff
記述子が含まれています。それがあるときはRing ``Buffer
、完全な、新しいパケットが破棄されます。NIC
メモリpackage
データを経由しないかもしれませんCPU
に直接コピーされたKernel
メモリ、このプロセスがある
DMA
:Directional Memory Access
主に高速なデータ交換に使用します。- 上の図から、
DMA
メモリのカーネルで動作していることがわかります。このメモリはDevice Driver
、Kernel
事前のアプリケーションの登録時に実際に登録されます。 - 最后需要注意,数据包到达
recv
Buffer
,TCP
就会回ACK
确认,既TCP
的ACK
表示数据包已经被操作系统内核收到,但并不确保应用层一定收到数据(例如这个时候系统crash
),因此一般建议应用协议层也要设计自己的确认机制。
数据包的发送过程
上图中红色的线条表示发送数据包的过程,和接收数据的路径相反,数据包的发送从上往下也经过了三层:用户态空间的应用、系统内核空间、最后到网卡驱动。
- 应用先将数据写入
TCP
send buffer
,TCP
层将send buffer
中的数据构建成数据包转交给IP
层。 IP
层会将待发送的数据包放入队列QDisc
(queueing discipline
)。- 数据包成功放入
QDisc
后,指向数据包的描述符sk_buff
被放入Ring
Buffer
输出队列,随后网卡驱动调用DMA
engine
将数据发送到网络链路上。