Почему DefaultHttpClient отправляет данные через половину -закрытого сокета?

Я использую DefaultHttpClientс ThreadSafeClientConnManagerна Android (2.3.x )для отправки HTTP-запросов на мой REST-сервер (, встроенный Jetty ).

После ~200 секунд простоя сервер закрывает TCP-соединение с [FIN]. Клиент Android отвечает [ACK]. Это должно и действительно оставляет сокет в наполовину -закрытом состоянии (сервер все еще слушает, но не может отправлять данные ).

Я ожидаю, что когда клиент снова попытается использовать это соединение (черезHttpClient.execute), DefaultHttpClientобнаружит полузакрытое -состояние, закроет сокет на стороне клиента (, отправив таким образом [FIN/ACK] для завершения закрытия ), и откроет новое соединение для запроса. Но есть загвоздка.

Вместо этого он отправляет новый HTTP-запрос через полузакрытый сокет -. Только после отправки обнаруживается полузакрытое состояние -и закрывается сокет на стороне клиента -(с отправкой [FIN] на сервер ). Конечно, сервер не может ответить на запрос (, он уже отправил свой [FIN] ), поэтому клиент считает, что запрос не удался, и автоматически повторяет попытку через новый сокет/соединение.

Конечным результатом является то, что сервер видит и обрабатывает две копии запроса.

Любые идеи о том, как это исправить? (Мой сервер делает все правильно со второй копией, но меня раздражает, что полезная нагрузка передается дважды.)

Разве DefaultHttpClient не должен обнаруживать, что сокет был закрыт, когда он впервые пытается записать новый HTTP-пакет, немедленно закрывать этот сокет и запускать новый? Я сбит с толку тем, как новый HTTP-запрос отправляется через сокет через несколько минут после того, как сервер отправил [FIN].

9
задан David B. 26 June 2012 в 17:17
поделиться