Тело HTTP-сообщения не получено

#http #sockets #client-server

#http #сокеты #клиент-сервер

Вопрос:

Я столкнулся с действительно странной проблемой на сайте одного из клиентов моей компании. Наша система пытается отправить HTTP-запросы на один из наших серверов на сайте. Сервер запущен на компьютере, который запускается из DMZ.

Клиент находится на Java, а сервер — на C #. Мой код отправляет HTTP-запрос следующим образом:

[Правка — заменено с псевдокода на реальный код]:

 Socket s = new Socket();
socket.connect([server address], timeout);

SocketOutputBuffer output = new SocketOutputBuffer (socket);

byte[] buffer = [creating the HTTP request headers]
output.write(buffer);
output.flush();

buffer = [creating the message body]
output.write(buffer);
output.flush();
  

При отладке клиентского приложения последний «вывод.flush ()»успешно завершен.
На стороне сервера я вижу, что на стороне сервера были получены только заголовки HTTP.

Странно то, что если я закрываю сокет после последнего сброса, тело сообщения поступает на сервер.

Есть мысли?

Большое спасибо.

Комментарии:

1. Трудно диагностировать, не видя вашего фактического кода. Поскольку вы знаете, что первая очистка работает, пробовали ли вы опустить ее и выполнить очистку только после текста сообщения?

2. Я обновил код и попробую опустить первую очистку. Спасибо.

Ответ №1:

Что за Java? Какая платформа? Вы закрываете сокет после этого? Вы правильно выключили розетку? Во многих случаях вы должны настроить сокет на завершение работы таким образом, чтобы он мог завершить отправку буферизованных данных (очистка не гарантируется …)

Комментарии:

1. Клиентская сторона работает на устройстве Android (2.1). Что это значит «перевести сокет в режим выключения»? вы имеете в виду закрытие сокета? Мое соединение передает потоковые данные на сервер, поэтому мне нужно, чтобы оно было открыто в течение всего сеанса. Спасибо за ответ.

2. @LiorOhana: О’Руни ссылается на параметры задержки сокета, которые определяют, как сокет ведет себя в отношении того, когда исходящие данные все еще ожидаются при закрытии сокета. По умолчанию сокет продолжает отправлять данные в фоновом режиме в течение определенного периода времени, даже если дескриптор приложения для сокета был аннулирован для дальнейшего использования.

3. @Remy: Просто чтобы убедиться, что я понимаю, вы имеете в виду, что, возможно, по какой-то причине мое соединение стало недействительным, и поэтому сброс может не сработать? 10x

4. @LiorOhana: нет, это не то, что я сказал. Когда я сказал «недействительно», я имел в виду, когда ваш код закрывает соединение, когда вы с ним закончите. Базовый сокет больше недействителен с точки зрения вашего приложения, но он все еще может выполнять фоновую работу, прежде чем ОС полностью аннулирует его. Если вы действительно хотите знать, что происходит, попробуйте использовать анализатор пакетов для просмотра сетевого трафика, убедитесь, что вызов flush () после отправки заголовков не приводит к преждевременному закрытию соединения.

5. @Remy: Моя проблема не в буферизации данных, которые не отправляются после закрытия сокета. Мне нужно поддерживать мое соединение открытым в течение всего сеанса. После каждой записи я вызываю flush, но я ничего не вижу на сервере (используя сниффер).