HTTP-запрос, странное поведение сокета - PullRequest
1 голос
/ 30 марта 2010

Я испытываю странное поведение при выполнении HTTP-запросов через сокеты, вот запрос:

POST https://example.com:443/service/XMLSelect HTTP/1.1
Content-Length: 10926
Host: example.com
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 1.0.3705)
Authorization: Basic XXX
SOAPAction: http://example.com/SubmitXml

Позже идет тело моего запроса с заданной длиной содержимого. После этого я получаю что-то вроде:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Tue, 30 Mar 2010 06:13:52 GMT

Так что, похоже, все в порядке здесь. Я прочитал все содержимое из сетевого потока и успешно получил ответ. Но мой сокет, который я делаю, опрашивает переключатели, это такие режимы:

write ( i write headers and request here )
read ( after headers sent i begin to receive response )
write ( STRANGE BEHAVIOUR HERE. WHY? here i send nothing really )
read ( here it switches to read back again )

последние два шага могут повторяться несколько раз. Итак, я хочу спросить, что приводит к изменению режима сокета? И в этом случае это не большая проблема, но когда я использую сжатие gzip в своем запросе (понятия не имею, как это связано) и прошу сервер отправить мне gzipped ответ следующим образом:

POST https://example.com:443/service/XMLSelect HTTP/1.1
Content-Length: 1076
Accept-Encoding: gzip
Content-Encoding: gzip
Host: example.com
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 1.0.3705)
Authorization: Basic XXX
SOAPAction: http://example.com/SubmitXml

Я получаю такой ответ:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Encoding: gzip
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Tue, 30 Mar 2010 07:26:33 GMT

2000
�

Я получил размер куска и заголовок GZIP, все в порядке. А вот что происходит с моей бедной маленькой розеткой:

write ( i write headers and request here )
read ( after headers sent i begin to receive response )
write ( STRANGE BEHAVIOUR HERE. And it finally sits here forever waiting for me to send something! But if i refer to HTTP I don't have to send anything more! )

С чем это может быть связано? Что он хочет, чтобы я отправил? Это проблема удаленного веб-сервера или я что-то пропустил?

PS Все актуальные сервисные ссылки и логины / пароли заменены на фальшивые:)

1 Ответ

2 голосов
/ 30 марта 2010

Сокет становится доступным для записи всякий раз, когда в сокете есть место буфер отправки . ОС не может точно знать, есть ли у вашего приложения больше данных для отправки, но знает о своих внутренних структурах, таких как буферы сокетов. Вы должны явно добавить / удалить сокет для записи fd_set для select(2) (включить / отключить событие EPOLLOUT для epoll(4)). Обычно это выполняется с помощью конечного автомата , как в libevent . Также опрос лучше всего работает с неблокирующими сокетами.

Надеюсь, это поможет.

...