QA@IT

webサーバーからのレスポンスがブラウザに届いたかを知る方法

7487 PV

端末から送信したhttpリクエストがサーバーには届いたが、
レスポンスが端末に届かなかった(通信エラー)場合について考えます。

端末側
リクエストに対するレスポンスが帰ってこないため通信エラーと認識できる

webサーバー側
レスポンスが端末に届いたかどうかは知る術は無い?
TCP/IPの3wayハンドシェイクで通信しているわけなので、
サーバーからのレスポンスを受けた端末がackを送信するはずです。
そのackをサーバーが受け取れたかどうかを知る方法はあるとは思いますが、
どのようにすれば、サーブレットで通信エラーを検知できるのかがわかりません。
例えばHttpServlet.doGetメソッドでexceptionが発生したりするのでしょうか?
ご存知の方がいらっしゃいましたら教えていただけると幸いです。

  • 「通信エラー」とは具体的に言うとどのような状況のことですか?パケットロスとは違うのですか? -
  • ここで言う通信エラーとは、サーバーからのレスポンスを端末が受け取れなかった場合の事を意味しています。
    例えば、サーバーから端末にレスポンスを返したが、端末がオフラインになってしまっており、端末にレスポンスが届かなかった場合を想定しています。
    -
  • ACKは通信前の出来事ですからdoGetが走り始めた時点でACKは受信してると言えるんじゃないですかね。ただもともとの質問の意図は「レスポンスがすべて届いたか」のようですのでACKは関係ないというだけなんですが。 -
  • field_onionさんのコメント、stripeさんの回答の付け足しになってしまいますが、サーバー側がレスポンスを返したということは、その時点でdoGet()メソッドは終了しているわけですよね? クライアントが正しく応答を受け取ったかどうかをdoGet()で捕捉するのはどうやっても無理な話なので、質問の意図がよくわからないのですが... -

回答

サーブレット上でサーバーがACKを受信したかどうかを確認する方法はないと思います。

クライアント向けにデータを送信した後に、サーバーがACKを受信しなかった場合は、送信したデータが損失したと判断して自動的にデータを再送することになります。
継続的にACKの受信ができなかったときは、継続的に再送して、その後タイムアウトするかどうかはOSの実装にもよると思います。

Javaは基本的にOSが提供するTCPソケットを利用しているので、ACKなどの処理は全てOS側で行っており、Java側ではACKの受信を検出できません。

また、クライアント側のブラウザで、サーバーからのレスポンスを待たずに「停止」ボタンを押すと、TCPのコネクションが切断されると思いますが、その際もサーブレット側でTCPのクローズを検出しなかったと思います。

サーブレット上でクライアントの死活を確認したいなら、WebSocketの利用を検討してみてください。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。