送受信ウィンドウ

データの送受信はコネクションの確立(TCP_ESTABLISHED状態)されたソケットの間で行われる(正確にはコネクション切断処理の時まで続くこともあるが)。

先にも述べたように、TCPはプロトコルレベルでのフロー制御メカニズムを備えている。受信マシンは、自マシンの能力に見合った受信可能量(windowsサイズ)を送信マシンに通知することにより実現する(TCPヘッダのwindowフィールドを利用)。

各マシン側は送信先マシンのwindowサイズにあわせ、一度に行うデータの送出量を決定し、データを即送出するか、送信バッファに一時的に保留するかを判断する。データの送出量とはデータを送り出したがまだACKの戻って来ていないパケットのデータ総量のことである。

下図に、どのようにLinuxがそのwindowとシーケンス番号を管理しているかを示す。データ送受信/ACK受信により、下図のsocket中の値が更新され、この値を元に処理が決定される。

img102.gif

まず、受信側ソケットから説明する。パケットが到着する毎にrcv_nxtがスライドしていく。それに従い受信ウィンドウも下へスライドしていく。受信バッファの余裕が少なくなって来たときは、受信ウィンドウを小さくし相手に通知する。受信バッファの余裕が無くなったときは受信ウィンドウは0として相手に通知する。

アプケーションからのデータ読み込み(recv処理)により、受信バッファに余裕が生まれた場合、受信ウィンドウを再び開き、相手に通知する。

  • rcv_nxtは、このシーケンス番号以前のデータは全て受信が 完了していることを示す。
  • rcv_wndは、このソケットの受信ウィンドウの大きさを示す。
  • copied_seqは、このシーケンス番号以前のデータは全て recvmsgにより読みだされていいることを示す。

次に送信側ソケットを説明する。送信側は、受信側から通知されたウィンドウサイズ以上のデータのデータを送りつけないようにする。受信側の処理が追い付かず(受信側のアプリケーションの受信処理が追い付かない)場合は、受信処理側からサイズ0のウィンドウが通知され送信処理が停止する。それにもかかわらずアプリケーションからの送信要求が続くと送信バッファがいっぱいになり、送信要求をブロックすることになる。

受信処理側から再度有限サイズのウィンドウが通知され送信処理が再開されると、送信要求のブロックを解除する。

  • snd_unaは、このシーケンス番号以前のデータを全て 受け取ったことを示す。
  • snd_nxtは、このシーケンス番号以前のデータは 送信したことを示す。snd_unaとsnd_nxt間のシーケンス番号を 持つデータはまだACK(応答)を受け取っていないことを表す。
  • send_wndは、相手のソケットの受信ウィンドウの大きさを示す。 (接続先から要求されたウィンドウサイズ) 送信時のパケットの大きさがあるため、snd_nxt - snd_una の値とはピッタリとは同じにはならない。
  • write_seqは、このシーケンス番号までのデータがアプリケーション から送信データとして渡されたことを示す。 snd_nxtとwrite_seqの間のシーケンス番号のデータは、 TCPプロトコルスタック内に保留されており、まだ一度も 送信されていないことを示す。

(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST
1