Java socke keep-alive (http protocol response)の使いかたについて。
Java http server の Keep-alive による Http Responsse の返し方に関して、
大雑把な説明ですが、参考になればと思い書いてみました。
重要な点は、3箇所だけです。
1. server socket のKeepAlive の設定
Socket sock = servsock.accept();
sock.setKeepAlive(true); // this is important No.1
2.http response ヘッダーの特に2か所の記述 Content-Length:xxx と 注1)Connection: Keep-Alive です。
注1) HTTP 1.1 では、必要ないみたい。
HTTP/1.1 200 OK\r\n or HTTP/1.0 200 OK\r\n
Date: xxxxx\r\n
Server: xxxxx\r\n
Content-Length: body-size\r\n // "body-size" is very important No.2
Keep-Alive: timeout=5, max=20\r\n // timeout -> sec ,here is a little important
Connection: Keep-Alive\r\n // here is important No.3 , but if HTTP 1.1 no need
Content-type: text/html\r\n\r\n
body-size は、実際の長さに必ず合わせます。(これが、今回、一番重要です!)
htmlや画像ファイルなどは、ファイルサイズが最初から分かるから問題ないのですが、
perl CGI の出力を受ける場合は、大変です。
CGIの出力データを一度バッファに取り込んで、最終の長さを計算するか、チャンクに分割してその都度送信するかだと思います。
apache のHTTPレスポンスを見ると、チャンクでは無いように見えますが!
Java http server の Keep-alive による Http Responsse の返し方に関して、
大雑把な説明ですが、参考になればと思い書いてみました。
重要な点は、3箇所だけです。
1. server socket のKeepAlive の設定
Socket sock = servsock.accept();
sock.setKeepAlive(true); // this is important No.1
2.http response ヘッダーの特に2か所の記述 Content-Length:xxx と 注1)Connection: Keep-Alive です。
注1) HTTP 1.1 では、必要ないみたい。
HTTP/1.1 200 OK\r\n or HTTP/1.0 200 OK\r\n
Date: xxxxx\r\n
Server: xxxxx\r\n
Content-Length: body-size\r\n // "body-size" is very important No.2
Keep-Alive: timeout=5, max=20\r\n // timeout -> sec ,here is a little important
Connection: Keep-Alive\r\n // here is important No.3 , but if HTTP 1.1 no need
Content-type: text/html\r\n\r\n
body-size は、実際の長さに必ず合わせます。(これが、今回、一番重要です!)
htmlや画像ファイルなどは、ファイルサイズが最初から分かるから問題ないのですが、
perl CGI の出力を受ける場合は、大変です。
CGIの出力データを一度バッファに取り込んで、最終の長さを計算するか、チャンクに分割してその都度送信するかだと思います。
apache のHTTPレスポンスを見ると、チャンクでは無いように見えますが!
サンプル コード!
tcp接続(socket 通信)で keep-alive を用いた場合でも、
サーバー側が、レスポンスデータを送信した後に、socket を クローズすると通常の接続の様に接続が切れてしまいます。
keep-alive の指定をすると、一度接続をclose しても、reopen などの方法が有るのでは、と 錯覚してしまいますが、そうでは無いようです。
おんちゃんも、この点は、インターネットで検索しましたが、ほとんどの人が、 reopen の方法はどうすればよいのか?とそちらの方向を見ている様でした。
おんちゃんも、同じ方向を考えていました(恥ずかしながら)。
結局の所、tcp接続 を維持したまま、リクエストデータとレスポンスデータの区切りを送り手側と、受け取り側が何らかの取り決めをしてシェイクハンドするしかありません。
たとえは、送り手側は、送信するデータの長さを相手に伝えて、受け手側がそのデータの長さ分受け取る、又は、データの区切れコードを取り決めるなどです。
普通に考えれば、しごく、当たり前の事でした。
ごく当たり前の事を、HTTPプロトコルは行っていると理解しました。
最初から、HTTPプロトコルの基本書などを充分読めば、どこかに記載があったのかもしれませんが、
以上が、事の顛末でした。
後、余談ですが、クライアント側の、URLConnection、HttpURLConnectionの場合は、
Java が、自動的にKeep-Alive処理をしてくれるみたいなので、connect() ,inputstream.close() を繰り返しても(shutdown をしなければ)持続接続されているみたいです。
tcp接続(socket 通信)で keep-alive を用いた場合でも、
サーバー側が、レスポンスデータを送信した後に、socket を クローズすると通常の接続の様に接続が切れてしまいます。
keep-alive の指定をすると、一度接続をclose しても、reopen などの方法が有るのでは、と 錯覚してしまいますが、そうでは無いようです。
おんちゃんも、この点は、インターネットで検索しましたが、ほとんどの人が、 reopen の方法はどうすればよいのか?とそちらの方向を見ている様でした。
おんちゃんも、同じ方向を考えていました(恥ずかしながら)。
結局の所、tcp接続 を維持したまま、リクエストデータとレスポンスデータの区切りを送り手側と、受け取り側が何らかの取り決めをしてシェイクハンドするしかありません。
たとえは、送り手側は、送信するデータの長さを相手に伝えて、受け手側がそのデータの長さ分受け取る、又は、データの区切れコードを取り決めるなどです。
普通に考えれば、しごく、当たり前の事でした。
ごく当たり前の事を、HTTPプロトコルは行っていると理解しました。
最初から、HTTPプロトコルの基本書などを充分読めば、どこかに記載があったのかもしれませんが、
以上が、事の顛末でした。
後、余談ですが、クライアント側の、URLConnection、HttpURLConnectionの場合は、
Java が、自動的にKeep-Alive処理をしてくれるみたいなので、connect() ,inputstream.close() を繰り返しても(shutdown をしなければ)持続接続されているみたいです。