Skip to content

MS_TCPUDP

nishi_74322014 edited this page Aug 3, 2026 · 1 revision

TCP, UDP

概要

  • TCP、UDPプロトコルについて説明する。
  • 現在のWindowsネットワークでは、TCP、UDPプロトコルが標準的に使われている。
  • 一般的なサービスやそのクライアント アプリケーションが使用するTCP、UDPのポート番号の一覧は、
    %windir%\system32\drivers\etc\services に記述されている。

UDPプロトコル

  • UDPは、IPアドレスを使用する「データグラム型通信」である。
  • また、ステートレスなサービスを実装しやすいという特徴があるが、
    データが相手に届いたことが保証されないという欠点がある。

TCPプロトコル

  • TCPは、IPアドレスを使用する「コネクション型通信」である。
    • 「コネクション型通信」は、初めに通信する者同士がデータ送受信のための通信路(コネクション)を確保する。
    • 以後、このコネクションを使ってデータが正しく相手に届くことを保証し、通信が完了後にコネクションを閉じる。
  • TCP/IPのプロトコル スタック(トランスポート層)までの保証になるため、
    • トランザクション処理のような、アプリケーションがストレージに結果を書き込むまでの信頼性は保障されない。
    • 通信媒体上のエラーでデータが相手に届かなかったりデータにエラーがあったりすると、再送処理を行って正しいデータが相手に届くように努力する。
      • 一般的には、データを受けた側では必ず確認応答(以下、ACKと略す)を返信して、
        データの送受信が正しく処理されたことを相互に確認する。
      • これによって、エラーのない信頼性のある通信を実現している。
        そして、どうしてもデータを送信できなければアプリケーションに送信失敗という結果を返す。

詳細

TCPとUDPの比較

ヘッダ

  • 宛先IPアドレスはIPヘッダに、
  • TCP, UDPヘッダにはポート番号が含まれる。

特徴

以下の表に、

  • UDP: データグラム型通信
  • TCP: コネクション型通信

の特徴をまとめた。

# 比較項目 データグラム型通信 コネクション型通信
1 通信目的 必ずしも応答を要求しない場合や、素早く相手にデータを届ける場合。 2つのアプリケーション間でデータをやり取りするために使う。
2 オーバーヘッド 小さい。
接続の確立処理などを行わず、直ぐに通信を開始。
応答確認やエラー検出なども行わない。
大きい。
接続を確立してから通信を開始し、
応答確認やエラー検出、再送、エラー訂正処理などを行う。
3 信頼性 低い。
エラーが発生しても再送処理などは行われない。
高い。
エラー検出や、エラー訂正処理などが行われる。
4 適する通信の種類 1対多の通信や、信頼性よりもリアルタイム性が要求される通信 データの送受信が保証される必要がある通信
  • UDP
    • データグラム型通信
    • 以下はアプリケーションで実装
      • パケット送信順に並べる
      • ロストしたパケットの再送要求など
    • 誤り検出
      • チェックサム・ヘッダがある。
      • 誤り訂正はできない。
      • 誤り検出されたらパケット廃棄
  • TCP
    • コネクション型通信
      • トランスポート層以上の経路で確立される。
      • 3ウェイ・ハンドシェイク (SYN、SYN ACK、ACK)
    • ウィンドウ制御
      TCPパケットを(ACKの確認なしで)連続して送信する
      • ウィンドウサイズを大きく調整して、データを纏めて送信できる。
      • ウィンドウサイズを小さく調整して、輻輳を回避できる。
    • 誤り訂正(チェックサム・ヘッダがある)
      • フォワード誤り訂正(前方誤り訂正、自己誤り訂正)
        受信側が誤り訂正する方式
      • バックワード誤り訂正(後方誤り訂正、再送誤り訂正)
        受信側が再送要求し、送信側が誤り訂正する方式

移行メモ(補足): 上記の 2 方式は誤り訂正の一般的な分類で、 TCP が使うのはバックワード(再送)方式のみ。 TCP のチェックサムは誤り「検出」用で、前方誤り訂正の機能は持たない。

TCPプロトコルの伝送制御

TCPプロトコルの伝送制御方法について簡単に説明する。

  • TCPでは、信頼性のある通信を実現するために、
    「相手にデータが届いたことをACKから必ず確認する」という手法を採用している。
    • ACKにはアプリケーションは介在せず、TCP/IPのプロトコル スタックにより処理される。
    • このような仕組みになっているため、上位アプリケーションはTCPプロトコルにおける伝送制御を意識することなく、
      信頼性のある「コネクション型通信」を利用することができる。
  • また、TCPでは効率の悪い「コネクション型通信」の転送方法を改善するために「ウィンドウ制御」という方式を採用している。

ウィンドウ制御

  • この方式により、
    • TCPパケットを(ACKの確認なしで)連続して送信することができるようになり、
    • 効率よく(ネットワークの帯域幅いっぱいまで)回線を利用できる。

ウィンドウ制御

TCPコネクションの状態

TCPプロトコルは「コネクション型通信」のプロトコルであり、このコネクションには種々の状態が存在する。

# 区分 状態 意味
1 ポート未使用状態側(双方の側) CLOSED 未使用状態のTCPポート。
通常これが表示されることはない。
2 リスニング ポートの作成側(パッシブ オープン側) LISTENING 待ち受け状態(リスニング状態)のポート。
クライアントからコネクション確立要求(以下、SYN)を受信し、
ACK(SYN/ACK)を返信して、SYN_RECEIVEDへ遷移する。
SYN_RECEIVED ACK(SYN/ACK)に対するACKの受信を待機している状態。
ACKの受信後、ESTABLISHEDへ遷移する。
3 コネクション確立要求の送信側(アクティブ オープン側) SYN_SENT サーバに対してSYNを送信し、ACK(SYN/ACK)の受信を待機している状態。
ACK(SYN/ACK)の受信後、ACKを送信してESTABLISHEDへ遷移する。
相手が無応答のときもこの状態になる。
4 コネクション確立状態側(双方の側) ESTABLISHED TCPコネクションが確立して通信している状態。
その後、終了処理を経由して以下のいずれかの状態に遷移する。
(1) コネクション終了要求(以下、FIN)を送信した場合、FIN_WAIT_1へ遷移する。
(2) FINを受信した場合、ACK(FIN ACK)を返信して、CLOSE_WAITへ遷移する。
5 コネクション終了要求の送信側(アクティブ クローズ側) FIN_WAIT_1 状況に応じて以下のいずれかの状態に遷移する。
(1) ACK(FIN ACK)を受信するとFIN_WAIT_2へ遷移する。
(2) 先に相手からのFINを受信するとCLOSINGへ遷移する。
FIN_WAIT_2 FINの受信を待機している状態。
FINの受信後、ACK(FIN ACK)を返信してTIME_WAITへ遷移する。
CLOSING FINに対するACKを返信し、ACK(FIN ACK)の受信を待機している状態。
ACK(FIN ACK)を受けるとTIME_WAITへ遷移する。
TIME_WAIT コネクションの終了待ち状態。
しばらく待ったあと、CLOSEDへ遷移して終了する。
6 コネクション終了要求の受信側(パッシブ クローズ側) CLOSE_WAIT ソケットを解放し、FINを送信してからLAST_ACKへ遷移する。
LAST_ACK FINに対するACK(FIN ACK)の受信を待機している状態。
ACK(FIN ACK)の受信後、CLOSEDへ遷移して終了する。
  • TCPコネクションのオープン処理
    • TCPでコネクションを確立するためには、3つのTCPパケット(SYN、SYN/ACK、ACK)の送受信を行う。
    • これを「3ウェイ ハンドシェイク」という。
    • RST / ACKで接続を拒否することもある。

TCPコネクションのオープン処理

  • TCPコネクションのクローズ処理
    クローズ処理では、TCPコネクションの両端のアプリケーションがそれぞれクローズを宣言するため、
    4つのTCPパケット(FIN×2、FIN ACK×2)を送受信することにより、TCPコネクションが終了する。

TCPコネクションのクローズ処理

TCP,UDPの状態の確認(netstatコマンド)

netstatコマンド

クライアントとサーバー

  • 一般的には
    • パッシブ オープン側がサーバ
    • アクティブ オープン側がクライアント
  • しかし、TCP/IPは、本質的にはクライアント・サーバを区別しない。
    • コネクション確立後は、プログラムからクライアント・サーバを区別しないで、
      ソケットのストリーム バッファにデータを書き込むだけでデータの送受信が可能となる。
    • 余談:FTP(アクティブ モード)など、クライアント側がパッシブ オープンするというプロトコルもある。
      • クライアント側がパッシブ オープンし、
      • サーバ側が(クライアント側のリスニング ポートに対して)アクティブ オープンする。

TCPのチューニング

新しいOSでは変更などもあるかも。

# 項目 説明
1 TCP/IPインターフェイス関連の設定
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
1-1 MTU DWORD IPパケットのサイズを決定する。大きなパケットで送信すると効率が良い。デフォルトは、1,500 byte。
2 TCP/IP関連の設定
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
2-1 RWIN(TcpWindowSize) DWORD TCPのウィンドウ制御に使用するバッファ。ウィンドウ サイズの最大値を設定する。
デフォルトは 65,535 byteで、チューニングの場合は値を大きくする。
また、ウィンドウ サイズは、MSSの整数倍に設定しておく。
2-2 MSS(Maximum Segment Size) DWORD 通常は MTU値から 40 Byte(TCPヘッダ、IPヘッダのデータ量)を引いた値に設定する。デフォルトは 1,460 byte。
2-3 DefaultTTL DWORD パケットを破棄するまでの時間(経由するルータ数など)。デフォルトは、Windows XP の場合 128。
2-4 SackOpts DWORD 1:有効(デフォルト)、0:無効
エラー再送が必要なパケットを効率的に通知する機能。これは必ず 1(有効)に設定しておく。
2-5 TcpMaxDupAcks DWORD パケット紛失を判断する通知回数を指定する。1 ~ 3 の間で設定し、デフォルトは 2。
遅延の大きいネットワークでRWINを拡大した場合は、3 回に設定すると良い。
2-6 Tcp1323Opts DWORD 3は、window scale、timestamps オプションを有効にする値。
RWIN値が 65,536 以上なら 3 に、65,535 以下なら 0 に設定。
2-7 EnablePMTUBHDetect DWORD 1:有効、0:無効(デフォルト)
殆どのネットワーク機器がこの検出オプションに対応しているため、
ブラックホール(経路MTU検出に応答しない機器)検出オプションは0(無効)で良い。
2-8 EnablePMTUDiscovery DWORD 1:有効(デフォルト)、0:無効
経路MTU検出オプションを有効にしてネットワーク上の機器に合わせてMTUを調整する。
これは必ず 1(有効)に設定しておく。
3 AFD (Ancillary Function Driver) のフロー制御パラメタ
HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters
3-1 LargeBufferSize DWORD 初期値:00001000 AFDが使用するバッファのサイズ
3-2 MediumBufferSize DWORD 初期値:000005e0 AFDが使用するバッファのサイズ
3-3 SmallBufferSize DWORD 初期値:00000080 AFDが使用するバッファのサイズ
3-4 TransmitWorker DWORD 有効値は0x10(デフォルト)か0x20のみ。
・0x10:Afd.sysがシステム スレッドを使用する。
・0x20:Afd.sysが同一スレッドを使用するため、コンテキストスイッチを削減できる。
3-5 DefaultReceiveWindow DWORD AFDが使用するバッファのサイズ。RWINより優先されるため、変更しない。
3-6 DefaultSendWindow DWORD AFDが使用するバッファのサイズ。

移行メモ(誤記): 原文は AFD の最後の 2 行がともに項番「3-5」だったため、 後者を 3-6 に振り直した。

  • Window Scalingオプション(TCPウィンドウ拡大オプション)/Time Stampsオプション
    • TcpWindowSize値を 65536以上に設定する場合に有効にする。
    • ただし Time Stamps は、TCPヘッダが12バイト増加するため、実効データ帯域が1%近く減少する。

補足(最新化): Windows Vista / Server 2008 以降は 自動チューニング(Receive Window Auto-Tuning) が既定で有効なため、 TcpWindowSize などのレジストリによる手動チューニングは 原則不要(かつ設定しても無視される場合がある)。 現行は netsh int tcp show global / Get-NetTCPSetting で状態を確認する。

チューニング例
  • 一般的な、TCPのチューニング
    • 「帯域幅は大きいが、遅延の大きいネットワーク間のノードの通信で、ウィンドウ サイズ(RWIN)を拡張することで、
      ACKのTCP制御パケットの数を削減し、性能を向上させる」というチューニング方法である。
    • RWINのサイズとは、相手側の確認応答(ACK)を待たずに一度に送信できるデータ サイズである。
  • TCPのチューニングの要素

TCPのチューニングの要素

  • ウィンドウ サイズ(RWIN)の値の計算方法

    回線速度 * pingが戻ってくる平均速度 = RWIN
    
  • 回線速度
    pingコマンドでサイズの大きいIPパケットを送信して求める。

    ping xxx.xxx.xxx.xxx -l 50000
      → Reply ... bytes=50000 time=10ms
    
    回線速度 ≒ データ サイズ / ( 所要時間 / 2 )
             = 50 (KB) / ( 10 / 2 ) (msec)
             = 10 (KB/msec)
             = 10,000,000 (バイト/秒) = 10 (MB/秒)
    

    確認のため、ファイル共有(SMB)を使用して、100MBのファイルの転送をテストしてみると良い。
    10秒程度で転送が完了すれば、pingを使用した方法でも回線速度が大方正しく測定できていることが確認できる。

    移行メモ(正誤): 原文はこの計算結果を 「10,000,000 (bps) = 10 (M bps)」としていたが、 割り出しているのは 1 秒あたりのバイト数なので、単位は B/s が正しい (bps に直すと 8 倍の 80 Mbps)。 直後の「100MB を 10 秒で転送」という検算も 10 MB/s を前提としており、 後続の RWIN の計算も MB/s のまま行われているため、 誤っているのは単位表記のみ。上記では B/s に改めた。

  • pingが戻ってくる平均速度
    1 パケット分のデータ(1,500 byte)を送信して求める。

    ping xxx.xxx.xxx.xxx -l 1500
      → Average = 2ms
    
  • 上記の環境(回線速度 10 MB/s、ping 平均 2 msec)で必要な RWIN は、

    RWIN = 10 (MB/sec) * 2 (msec) = 20 (KB) = 20,000 (byte)
    
  • 結果

    • デフォルトのRWINの値は、65,535 byteであるため、帯域幅は大きいが、
      遅延の大きいネットワーク間のノードの通信でない限り、
      TCPのチューニング(RWINの拡張)は基本的に必要無い。
    • また、以下のチューニング ポイントも考慮する。
      • RWINは、MSSの整数倍に設定する。
      • パケット再送信が起きる場合は、RWINを1.5倍する。

Tags: IT国際標準, インフラストラクチャ, 通信技術

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally