ぼやきごと/2010-04-08/TCP通信プログラミング体験談 のバックアップ(No.1)


TCP通信プログラミング体験談

TCP通信プログラム実装時の体験談。

次のようなよくあるTCP送受信を行うプログラムを作りました。

  1. 【クライアント】ヘッダ情報(データサイズ情報を含む)を送信。
  2. 【クライアント】データを送信。
  3. 【サーバ】ヘッダ情報およびデータを受信。
  4. 【サーバ】データを処理し、結果データを作成。
  5. 【サーバ】ヘッダ情報(結果データサイズ情報を含む)を送信。
  6. 【サーバ】結果データを送信。
  7. 【クライアント】ヘッダ情報および結果データを受信。

送受信共にヘッダは20バイト未満、データと合わせても1KB未満のサイズで、サーバ側の処理も一瞬で終わるようなものです。

ところが、このプログラムの送受信1回あたりの所要時間を計測したところ、約300ミリ秒も掛かっていました。
3〜4回送受信するだけで1秒経ってしまう計算です。

何がボトルネックになっているのか細かく計測したところ、所要時間の9割以上は select 関数での受信待ち時間でした*1
ちなみに、 send 関数や recv 関数は一瞬で終わっていました。

そこで、次のようにヘッダとデータを一度に送信することで送信回数を減らしてみました。

  1. 【クライアント】ヘッダ情報(データサイズ情報を含む)およびデータを一度に送信。
  2. 【サーバ】ヘッダ情報およびデータを受信。
  3. 【サーバ】データを処理し、結果データを作成。
  4. 【サーバ】ヘッダ情報(結果データサイズ情報を含む)および結果データを一度に送信。
  5. 【クライアント】ヘッダ情報および結果データを受信。

要するに、今まで send(ヘッダ); send(データ); とやっていたところを send(ヘッダ+データ); にしてみたということです。
受信側の処理は変えていません。

そして再び送受信1回あたりに掛かる時間を計測してみました。
予想では半分の150ミリ秒くらいにはなるかと思っていましたが、結果はなんと約15〜30ミリ秒
分けて送っていた時の10倍以上もの速度になりました。

「TCP通信ではNバイトのデータを1回で送信しても1バイトずつN回に分けて送信しても所要時間は同じ」というような話をどこかで聞いたような気がするのですが、一体どうしてここまで差が出たのでしょうか…。
まだまだソケットプログラミングは勉強不足だなと感じた一件でした。

Category: [プログラミング][C++] - 2010-04-08 00:32:59

*1 ブロッキングしないようにタイムアウトを0ミリ秒指定した上でループさせています