-
Notifications
You must be signed in to change notification settings - Fork 0
MS_TCPUDP
- 戻る(通信技術、ネットワークの基礎編)
- TCP、UDPプロトコルについて説明する。
- 現在のWindowsネットワークでは、TCP、UDPプロトコルが標準的に使われている。
- 一般的なサービスやそのクライアント アプリケーションが使用するTCP、UDPのポート番号の一覧は、
%windir%\system32\drivers\etc\servicesに記述されている。
- UDPは、IPアドレスを使用する「データグラム型通信」である。
- また、ステートレスなサービスを実装しやすいという特徴があるが、
データが相手に届いたことが保証されないという欠点がある。
- TCPは、IPアドレスを使用する「コネクション型通信」である。
- 「コネクション型通信」は、初めに通信する者同士がデータ送受信のための通信路(コネクション)を確保する。
- 以後、このコネクションを使ってデータが正しく相手に届くことを保証し、通信が完了後にコネクションを閉じる。
- TCP/IPのプロトコル スタック(トランスポート層)までの保証になるため、
- トランザクション処理のような、アプリケーションがストレージに結果を書き込むまでの信頼性は保障されない。
- 通信媒体上のエラーでデータが相手に届かなかったりデータにエラーがあったりすると、再送処理を行って正しいデータが相手に届くように努力する。
- 一般的には、データを受けた側では必ず確認応答(以下、ACKと略す)を返信して、
データの送受信が正しく処理されたことを相互に確認する。 - これによって、エラーのない信頼性のある通信を実現している。
そして、どうしてもデータを送信できなければアプリケーションに送信失敗という結果を返す。
- 一般的には、データを受けた側では必ず確認応答(以下、ACKと略す)を返信して、
- 宛先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では、信頼性のある通信を実現するために、
「相手にデータが届いたことをACKから必ず確認する」という手法を採用している。- ACKにはアプリケーションは介在せず、TCP/IPのプロトコル スタックにより処理される。
- このような仕組みになっているため、上位アプリケーションはTCPプロトコルにおける伝送制御を意識することなく、
信頼性のある「コネクション型通信」を利用することができる。
- また、TCPでは効率の悪い「コネクション型通信」の転送方法を改善するために「ウィンドウ制御」という方式を採用している。
- この方式により、
- TCPパケットを(ACKの確認なしで)連続して送信することができるようになり、
- 効率よく(ネットワークの帯域幅いっぱいまで)回線を利用できる。

- また、「ウィンドウ制御」では「シーケンス番号」と「ウィンドウ サイズ」(送受信用のバッファ)が重要な役割を果たす。
- 「シーケンス番号」は「ウィンドウ サイズ」上のデータの位置を表し、パケットの到着順が前後しても問題無いように使用される。
- また、「ウィンドウ サイズ」はデータの流れを許可したり禁止したりすることに使用される。
- [参考] @IT > 基礎から学ぶWindowsネットワーク 第14回 信頼性のある通信を実現するTCPプロトコル(その1)2.シーケンス番号とウィンドウ制御
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コネクションの両端のアプリケーションがそれぞれクローズを宣言するため、
4つのTCPパケット(FIN×2、FIN ACK×2)を送受信することにより、TCPコネクションが終了する。

- 一般的には
- パッシブ オープン側がサーバ
- アクティブ オープン側がクライアント
- しかし、TCP/IPは、本質的にはクライアント・サーバを区別しない。
- コネクション確立後は、プログラムからクライアント・サーバを区別しないで、
ソケットのストリーム バッファにデータを書き込むだけでデータの送受信が可能となる。 - 余談:FTP(アクティブ モード)など、クライアント側がパッシブ オープンするというプロトコルもある。
- クライアント側がパッシブ オープンし、
- サーバ側が(クライアント側のリスニング ポートに対して)アクティブ オープンする。
- コネクション確立後は、プログラムからクライアント・サーバを区別しないで、
新しいOSでは変更などもあるかも。
- Windows XP での TCP/IP と NBT の構成パラメータ(KB314053)
- TCPのチューニング パラメータ(Windows 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)を待たずに一度に送信できるデータ サイズである。
- 「帯域幅は大きいが、遅延の大きいネットワーク間のノードの通信で、ウィンドウ サイズ(RWIN)を拡張することで、
- 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倍する。
- デフォルトのRWINの値は、65,535 byteであるため、帯域幅は大きいが、
Tags: IT国際標準, インフラストラクチャ, 通信技術
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。