ichou1のブログ

主に音声認識、時々、データ分析のことを書く

ソケットプログラミングにおけるKeepAliveの考え方メモ

ブラウザ上で閲覧する1つのWEBページは、HTML、JavaScriptCSS等、複数のファイルから構成されることがほとんど。
ソケットプログラムを書くとなると、1ファイル=1要求として関数を書くことになると思われるが、
ソケットの作成は、毎回、行わなければならないのか否か。

以下、1つのファイルを要求する関数の骨組み(イメージ)

DoOneRequest("URL"){

  soc = ClientSocket(ホスト名, ポート);  /* 内部でsocket(2)とconnect(2) */

  /* 要求 */
  send(soc, …);

  /* 応答 */
  recv(soc, …);

  close(soc);  <- ここ。再利用ができるのかどうか
}

結論は、1つのファイル要求のたびに、ソケットの作成が必要と思われる。

クライアント側はConnectionヘッダに"keep-alive"を付けてソケットを再利用しようとしても、
サーバ側でソケットを閉じられてしまえば、send (2)に失敗する。

ならば、recv(2)が終わったらclose(2)した方がゴミが残らなくて良いのか。
もっといえば、Connectionヘッダに"close"を付けるのがスマートか(省略時のデフォルトは"keep-alive")

ここを少し掘り下げてみると、

HTTPはステートレスである

ということが前提条件としてある。

ApacheとKeep Aliveの実験 | noriyuruの日記 | スラド

サーバ側をApacheとした場合、KeepAlive周りに関連する設定は以下。

  • KeepAlive
  • MaxKeepAliveRequests
  • KeepAliveTimeout

個人的には、"MaxKeepAliveRequests"(KeepAliveが有効な通信において、いくつのリクエストを許すか)が分かりにくいと感じた。
(なお、先入観では、"KeepAlive通信として管理するRequestの数"だと思った。サーバ側で処理できるRequest数はプロセス/スレッドの数に依存する)
以下のサイトの例えが分かりやすい。

apacheのKeepAliveをそれなりに考えてみた | 池袋メガネプログラマーノート

サーバ側で通信状態を管理しようとすれば、その分のリソースを消費するし、さっさと切断するのは妥当な設定と言える。