詳細に記載されている、のは、データが受信されたかを見てみましょう。データ受信は、ネットワークスタックが入ってくるパケットをどのように処理するかの手順である です。図 3は、ネットワークスタックが受信したパケットをどのように処理するかを示しています。 最初に、NICはパケットをそのメモリに書き込みます。 CRCチェックを実行してパケットが有効であるかどうかを確認し、 パケットをホストのメモリバッファに送信します。このバッファは、ドライバによってカーネルに既に が要求され、パケットを受信するために が割り当てられたメモリです。バッファが割り当てられた後、ドライバ はNICへのメモリアドレスとサイズを通知します。 NICが パケットを受信しても、ドライバによって割り当てられたホストバッファがない場合、NICはパケットを廃棄することがあります。
パケットをホストメモリバッファに送信した後、NICはホストOSに 割り込みを送信します。
ドライバは、新しいパケットを処理できるかどうかをチェックします。 これまでのところ、製造元の で定義されているドライバNIC通信プロトコルが使用されています。
ドライバがパケットを上位レイヤに送信する必要がある場合、パケット は、OSがパケットを理解するためにOSで使用するパケット構造でラップする必要があります。たとえば、Linuxのsk_buff、 BSDシリーズカーネルのmbuf、およびMicrosoft WindowsのNET_BUFFER_LISTは、対応するOSのパケット構造 です。ドライバは、 ラップされたパケットを上位レイヤに送信します。パケットが有効であるかどうか
イーサネット層をチェックした後 デマルチプレクス上位プロトコル(ネットワークプロトコル)。現時点では、 はイーサネットヘッダーのethertype値を使用します。 IPv4 ethertype の値は0x0800です。イーサネットヘッダーを削除してから、 パケットをIPレイヤーに送信します。
IP層は、パケットが有効かどうかもチェックします。つまり、 は、IPヘッダーチェックサムをチェックします。論理的には、 がIPルーティングを実行し、ローカルシステムがパケットを処理するようにするかどうか、つまり か、そのパケットを他のシステムに送信する必要があります。パケットがローカルシステムによって で処理されなければならない場合、IP層はIPヘッダのプロト値を参照して上位プロトコル (トランスポートプロトコル)を逆多重化する。 TCPプロトコルの値は6です.IPヘッダーを削除してから、 パケットをTCPレイヤーに送信します。パケットが 有効であるかどうか、下位層、TCP層のチェックと同様に
。また、TCPチェックサムもチェックします。前述のように、現在のネットワークスタックはチェックサムオフロードを使用しているので、カーネルではなく、NICによって計算されたTCPチェックサムは です。
そして、それは、パケットが接続されているTCP制御ブロックを検索します。 パケットの<source IP, source port, target IP, target port>
が識別子として使用されます。接続を検索した後、 はパケットを処理するプロトコルを実行します。新しい データを受信した場合は、データを受信ソケットバッファに追加します。 TCP状態によれば、新しいTCPパケット(例えば、ACKパケット)を送信することができる。 TCP/IP受信パケット処理が完了しました。
受信ソケットバッファのサイズは、TCPウィンドウを受信します。受信ウィンドウが の場合、特定のポイントである にTCPスループットが向上します。以前は、ソケットバッファサイズは、アプリケーションまたはOS構成の で調整されていました。最新のネットワークスタックは、受信ソケットバッファサイズを調整するための 機能、すなわち受信 ウィンドウを自動的に有する。
アプリケーションがリードシステムコールを呼び出すと、領域が のカーネル領域に変更され、ソケットバッファ内のデータがユーザ領域のメモリ にコピーされます。コピーされたデータはソケット バッファから削除されます。そして、TCPが呼び出されます。ソケットバッファに新しいスペースがあるため、TCPは受信 ウィンドウを増加させます。そして、プロトコルの状態に応じて パケットを送信します。パケットが転送されない場合、 システムコールは終了します。