Как получить больше 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 байт?
Спасибо в продвижение.
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