Как получить более 1440 через розетку - PullRequest
4 голосов
/ 21 мая 2011

Я написал две простые программы: сервер и клиент, используя сокеты на C ++ (Linux).Изначально это был пример клиент-серверного приложения (отправка эхо-сообщения и получение ответа).Затем я изменил клиента для реализации HTTP GET (теперь я больше не использую свой пример сервера).Это работает, но какой бы размер буфера я ни установил, клиент получает только 1440 байт.Я хочу получить всю страницу в буфер.Я думаю, что это связано со свойствами TCP, и я должен реализовать некоторый цикл в коде моего клиента, чтобы охватить все части ответа.Но я не знаю, что именно я должен делать.

Это мой код:

...
int bytesSent = send(sock, tmpCharArr, message.size()+1, 0);
// Wait for the answer. Receive it into the buffer defined.
int bytesRecieved = recv(sock, resultBuf, 2048*100, 0);
...

2048 * 100 - это размер буфера, и я думаю, что этого более чем достаточно для относительнонебольшая WEB-страница, используемая для тестирования.Но, как я уже говорил, я получаю только 1440 байтов.

Что я могу сделать с вызовом функции recv () для захвата всех "частей" ответа, когда ответ сервера превышает 1440 байт?

Заранее спасибо.

Ответы [ 2 ]

6 голосов
/ 21 мая 2011

Размер буфера определяется факторами, не зависящими от вас (маршрутизаторы, ADSL-соединения, IP-стеки и т. Д.).Стандартный способ передачи больших объемов данных - это повторный вызов recv().

1 голос
/ 21 мая 2011

HTTP работает через TCP, и чтобы лучше понять работу TCP-сокетов, вы должны рассматривать их как поток, а не как пакеты.

Для большей ясности прочитайте мой предыдущий пост: рекомбинация разбиенияПакет TCP с флеш-сокетами

Что касается того, почему вы получаете только 1400 (или около того) байтов, вы должны понимать MTU и фрагментацию.Подводя итог, MTU (Maximum Transmission Unit) - это способность сети передавать один пакет определенного максимального размера.MTU всей сети является самым низким MTU среди всех задействованных маршрутизаторов.Фрагментация разделяет пакеты, если вы пытаетесь отправить один пакет размером больше MTU этой сети.

Для лучшего понимания MTU и фрагментации читайте: http://www.miislita.com/internet-engineering/ip-packet-fragmentation-tutorial.pdf

Теперь, что касается получения всей страницы в буфере, одна альтернатива - продолжать вызывать recv() и добавлять полученные данные в буфер, пока recv() не вернет zero.Это будет работать, потому что обычно веб-сервер закрывает TCP-соединение после отправки вам ответа.Однако этот метод не будет работать, если веб-сервер не закроет сеанс (возможно, keep-alives являются конфигурациями).

Следовательно, правильным решением будет продолжение приема до тех пор, пока вы не получите HTTPзаголовок.Взгляните и определите длину всего HTTP-ответа (Content-Length:), а затем продолжайте получать, пока не получите точное количество байтов, которое вы должны были получить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...