「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
- 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対多の通信や、信頼性よりもリアルタイム性が要求される通信 | データの送受信が保証される必要がある通信 |
- 以下はアプリケーションで実装
- パケット送信順に並べる
- ロストしたパケットの再送要求など
- 誤り検出
- チェックサム・ヘッダがある。
- 誤り訂正はできない。
- 誤り検出されたらパケット廃棄
- コネクション型通信
- トランスポート層以上の経路で確立される。
- 3ウェイ・ハンドシェイク (SYN、SYN ACK、ACK)
- ウィンドウ制御
TCPパケットを(ACKの確認なしで)連続して送信する
- ウィンドウサイズを大きく調整して、データを纏めて送信できる。
- ウィンドウサイズを小さく調整して、輻輳を回避できる。
- フォワード誤り訂正(前方誤り訂正、自己誤り訂正
受信側が誤り訂正する方式
- バックワード誤り訂正(後方誤り訂正、再送誤り訂正
受信側が再送要求し、送信側が誤り訂正する方式
TCPプロトコルの伝送制御 †
TCPプロトコルの伝送制御方法について簡単に説明する。
- TCPでは、信頼性のある通信を実現するために、
「相手にデータが届いたことをACKから必ず確認する」という手法を採用している。
- ACKにはアプリケーションは介在せず、TCP/IPのプロトコル スタックにより処理される。
- このような仕組みになっているため、上位アプリケーションはTCPプロトコルにおける伝送制御を意識することなく、
信頼性のある「コネクション型通信」を利用することができる。
- また、TCPでは効率の悪い「コネクション型通信」の転送方法を改善するために「ウィンドウ制御」という方式を採用している。
ウィンドウ制御 †
- この方式により、
- TCPパケットを(ACKの確認なしで)連続して送信することができるようになり、
- 効率よく(ネットワークの帯域幅いっぱいまで)回線を利用できる。
- また、「ウィンドウ制御」では「シーケンス番号」と「ウィンドウ サイズ」(送受信用のバッファ)が重要な役割を果たす。
- 「シーケンス番号」は「ウィンドウ サイズ」上のデータの位置を表し、パケットの到着順が前後しても問題無いように使用される。
- また、「ウィンドウ サイズ」はデータの流れを許可したり禁止したりすることに使用される
- 「ウィンドウ制御」における「シーケンス番号」と「ウィンドウ サイズ」の役割は、下記のページを参考にできる。
TCPコネクションの状態 †
TCPプロトコルは「コネクション型通信」のプロトコルであり、このコネクションには種々の状態が存在する。
- TCPコネクションの状態の種類
- TCPコネクションには下記の状態がある。
- これは、現時点の状態がTCPコネクションの
「オープン」 ⇒ 「通信経路の確保」 ⇒ 「クローズ」
といったシーケンス中の何処にあるかを示すものである。
# | 区分 | 状態 | 意味 |
1 | ポート未使用状態側(双方の側) |
1-1 | | CLOSED | 未使用状態のTCPポート。 通常これが表示されることはない。 |
2 | リスニング ポートの作成側(パッシブ オープン側) |
2-1 | | LISTENING | 待ち受け状態(リスニング状態)のポート。 クライアントからコネクション確立要求(以下、SYN)を受信し、 ACK(SYN/ACK)を返信して、SYN_RECEIVEDへ遷移する。 |
2-2 | | SYN_RECEIVED | ACK(SYN/ACK)に対するACKの受信を待機している状態。 ACKの受信後、ESTABLISHEDへ遷移する。 |
3 | コネクション確立要求の送信側(アクティブ オープン側) |
3-1 | | SYN_SENT | サーバに対してSYNを送信し、ACK(SYN/ACK)の受信を待機している状態。 ACK(SYN/ACK)の受信後、ACKを送信してESTABLISHEDへ遷移する。 相手が無応答のときもこの状態になる。 |
4 | コネクション確立状態側(双方の側) |
4-1 | | ESTABLISHED | TCPコネクションが確立して通信している状態。 その後、終了処理を経由して以下のいずれかの状態に遷移する。 (1) コネクション終了要求(以下、FIN)を送信した場合、FIN_WAIT_1へ遷移する。 (2) FINを受信した場合、ACK(FIN ACK)を返信して、CLOSE_WAITへ遷移する。 |
5 | コネクション終了要求の送信側(アクティブ クローズ側) |
5-1 | | FIN_WAIT_1 | 状況に応じて以下のいずれかの状態に遷移する。 (1) ACK(FIN ACK)を受信するとFIN_WAIT_2へ遷移する。 (2) 先に相手からのFINを受信するとCLOSINGへ遷移する。 |
5-2 | | FIN_WAIT_2 | FINの受信を待機している状態。 FINの受信後、ACK(FIN ACK)を返信してTIME_WAITへ遷移する。 |
5-3 | | CLOSING | FINに対するACK返信し、ACK(FIN ACK)の受信を待機している状態。 ACK(FIN ACK)を受けるとTIME_WAITへ遷移する。 |
5-4 | | TIME_WAIT | コネクションの終了待ち状態。 しばらく待ったあと、CLOSEDへ遷移して終了する。 |
6 | コネクション終了要求の受信側(パッシブ クローズ側) |
6-1 | | CLOSE_WAIT | ソケットを解放し、FINを送信してからLAST_ACKへ遷移する。 |
6-2 | | LAST_ACK | FINに対するACK(FIN ACK)の受信を待機している状態。 ACK(FIN ACK)の受信後、CLOSEDへ遷移して終了する。 |
- 状態の状態遷移図
- 次に、この状態の状態遷移図を示す。
- ただし、コネクション終了要求(FIN)が重複し、
FIN_WAIT_1の状態で先に相手からのFINを受け取った時の状態遷移は割愛した。
- TCPコネクションのオープン処理
- TCPでコネクションを確立するためには、
3つのTCPパケット(SYN、ACK / SYN、ACK)の送受信を行う。
- これを「3ウェイ ハンドシェイク」という。
- RST / ACKで接続を拒否することもある。
- TCPコネクションのクローズ処理
クローズ処理では、TCPコネクションの両端のアプリケーションがそれぞれクローズを宣言するため、
4つのTCPパケット(FIN*2、FIN ACK*2)を送受信することにより、TCPコネクションが終了する。
クライアントとサーバー †
- 一般的には
- パッシブ オープン側がサーバ
- アクティブ オープン側がクライアント
- しかし、TCP/IPは、本質的にはクライアント・サーバを区別しない。
- コネクション確立後は、プログラムからクライアント・サーバを区別しないで、
ソケットのストリーム バッファにデータを書き込むだけでデータの送受信が可能となる。
- 余談:FTP(アクティブ モード)など、クライアント側がパッシブ オープンするというプロトコルもある。
- クライアント側がパッシブ オープンし、
- サーバ側が(クライアント側のリスニング ポートに対して)アクティブ オープンする。
TCPのチューニング †
新しいOSでは変更などもあるかも。
# | 項目 | 型 | 説明 |
1 | TCP/IPインターフェイス関連の設定 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet?\Services\Tcpip\Parameters\Interfaces |
1-1 | | MTU | DWORD | IPパケットのサイズを決定する。大きなパケットで送信すると効率が良い。デフォルトは、1,500 byte。 |
2 | TCP/IP関連の設定 HKEY_LOCAL_MACHINE\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)が使用するフロー制御に関するパタメタ HKEY_LOCAL_MACHINE\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-5 | | DefaultSendWindow? | DWORD | AFDが使用するバッファのサイズ。 |
- Window Scalingオプション(TCPウィンドウ拡大オプション)
- TcpWindowSize?値を 65536以上に設定する場合に有効にする。
- Time Stampsオプション
- TcpWindowSize?値を 65536以上に設定する場合に有効にする。
- ただし、TCPヘッダが12バイト増加するため、実効データ帯域が1%近く減少する。
- 一般的な、TCPのチューニング
- 一般的な、TCPのチューニングとは、「帯域幅は大きいが、遅延の大きいネットワーク間のノードの通信で、ウィンドウ サイズ(RWIN) を拡張することで、
「TCPプロトコルの伝送制御」で説明した、ACKのTCP制御パケットの数を削減し、性能を向上させる」というチューニング方法である。
- RWINのサイズとは、相手側の確認応答(Ack)を待たずに一度に送信できるデータ サイズである。
- 回線速度
「回線速度」は、以下の方法で求める。
- pingコマンドを使用してサイズの大きいIPパケットを送信する
(ここでは、50 KBのIPパケットを送信するように指定した。pingコマンドでは、最大65.5 KBのIPパケットを送信できる)。
C:\Documents and Settings\Administrator>ping xxx.xxx.xxx.xxx -l 50000
Pinging xxx.xxx.xxx.xxx with 50000 bytes of data:
Reply from xxx.xxx.xxx.xxx: bytes=50000 time=10ms TTL=128
Reply from xxx.xxx.xxx.xxx: bytes=50000 time=10ms TTL=128
Reply from xxx.xxx.xxx.xxx: bytes=50000 time=10ms TTL=128
Reply from xxx.xxx.xxx.xxx: bytes=50000 time=10ms TTL=128
Ping statistics for xxx.xxx.xxx.xxx:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 10ms, Maximum = 10ms, Average = 10ms
- 回線速度は、以下の式で求めることができるので、
回線速度 ≒ データ サイズ / ( 所要時間 / 2 )
この式に当て込んで、回線速度は、
回線速度 = 50 (KB) / ( 10 / 2 ) (msec)
= 50 / 5 (KB) / (msec)
= 10 * (1,000 (byte)) / (( 1 / 1,000 ) (sec))
= 10 * 1,000 * 1,000 (bps)
= 10,000,000 (bps)
= 10 (M bps)
10M bpsと算出できる。
確認のため、ファイル共有(SMB)を使用して、100MBのファイルの転送をテストしてみると良い。
10秒程度で転送が完了すれば、pingを使用した方法でも回線速度が大方正しく測定できていることが確認できる。
- pingが戻ってくる平均速度
「pingが戻ってくる平均速度」は、以下の方法で求める。
- pingコマンドを使用して 1 パケット分のデータ(1,500 byte)を送信する。
C:\Documents and Settings\Administrator>ping xxx.xxx.xxx.xxx -l 1500
Pinging xxx.xxx.xxx.xxx with 1500 bytes of data:
Reply from xxx.xxx.xxx.xxx: bytes=1500 time=2ms TTL=128
Reply from xxx.xxx.xxx.xxx: bytes=1500 time=2ms TTL=128
Reply from xxx.xxx.xxx.xxx: bytes=1500 time=2ms TTL=128
Reply from xxx.xxx.xxx.xxx: bytes=1500 time=2ms TTL=128
Ping statistics for xxx.xxx.xxx.xxx:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 2ms, Maximum = 2ms, Average = 2ms
この時のAverageの値である2ミリ秒が「pingが戻ってくる平均速度」となる。
- 上記の環境(100BASE-TXのローカル ネットワーク間のノードの通信)
● 回線速度 :10 M bps
● pingが戻ってくる平均速度 :2 m sec
で必要なRWINの値は、
回線速度 * pingが戻ってくる平均速度 = RWIN
の計算方法式に当てはめ、次のようになる。
RWIN = 10 ( MB / sec ) * 2 ( msec )
= 10 * (1,000 (KB / sec)) * (( 2 / 1,000 ) (sec))
= 10 * 1,000・( 2 / 1,000 ) ((KB / sec) (sec))
= 10 * 2 ( KB )
= 20 ( KB )
= 20,000 ( byte )
- 結果
- デフォルトのRWINの値は、65,535 byteであるため、帯域幅は大きいが、
遅延の大きいネットワーク間のノードの通信でない限り、
TCPのチューニング(RWINの拡張)は基本的に必要無い。
- また、以下のチューニング ポイントも考慮する。
● RWINは、MSSの整数倍に設定する。
● パケット再送信が起きる場合は、RWINを1.5倍する。
Tags: :インフラストラクチャ, :通信技術, :Windows, :シェル