Android(2.3.x)でThreadSafeClientConnManager
とDefaultHttpClient
を使用して、自分のRESTサーバー(埋め込みJetty)にHTTPリクエストを送信しています。DefaultHttpClientがハーフクローズソケットでデータを送信するのはなぜですか?
アイドル時間が200秒後に、サーバーはTCP接続を[FIN]で閉じます。 Androidクライアントは[ACK]で応答します。これはソケットを半閉じた状態(サーバはまだリスンしていますが、データを送信することはできません)のままにしておきます。
クライアントがその接続を(HttpClient.execute
経由で)再度使用しようとすると、DefaultHttpClient
はハーフクローズ状態を検出し、クライアント側のソケットを閉じます(したがって、[FIN/ACK]を送信して閉じる)し、要求の新しい接続を開きます。しかし、擦れがあります。
代わりに、ハーフクローズソケットを介して新しいHTTP要求を送信します。送信後のみハーフクローズ状態が検出され、ソケットはクライアント側で閉じられます([FIN]がサーバーに送信されます)。もちろん、サーバーは要求に応答できません(既に[FIN]を送信していた)ので、クライアントは要求が失敗したと判断し、新しいソケット/接続を介して自動的に再試行します。
最終的に、サーバーは2つの要求のコピーを見て処理します。
これを修正する方法についてのご意見はありますか? (私のサーバーは2番目のコピーで正しいことを行いますが、ペイロードが2回送信されるのは面倒です)
DefaultHttpClientは、新しいHTTPパケットの書き込みを最初に試みたときにソケットが閉じられたことを検出しません。そのソケットをすぐに閉じて、新しいソケットを開始しますか?私は、サーバーが[FIN]を送信した後、新しいHTTPリクエストがソケットでどのように送信されるのか、困惑しています。
'AndroidHttpClient'がまったく同じ振る舞い、おそらくあなたはそれを使用して試すことができます...(' ThreadSafeClientConnManager'と、すなわち 'DefaultHttpClient'は、スレッドの安全性を確保するために)ん?私は、ソケット接続の仕組みについて詳しくは分かりませんが、ちょっとした提案があります。 –