Как получить больше 1440 через розетку



Я написал две простые программы сервер и клиент, используя сокеты в 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-это размер буфера, и я думаю, что этого более чем достаточно для относительно небольшой веб-страницы, используемой для тестирования. Но, как я уже упоминал, я получаю только 1440 байт.

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



Спасибо в продвижение.

519   2  

2 ответов:

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

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

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

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

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

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

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

Comments

    Ничего не найдено.