Отправка и получение сокетов (TCP / IP) - PullRequest
0 голосов
/ 02 марта 2012

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

  1. Если я вызову recv (или любую другую альтернативную (низкоуровневую) функцию), когда есть несколько пакетов, ожидающих чтения, вернет ли их все в стек или только один из них (или часть первого, если моего буфера недостаточно)?
  2. Если я отправляю длинный пакет, требующий полной отправки нескольких итераций, считается ли он одним пакетом или несколькими пакетами? Это в основном вопрос, отмечает ли это, что отправленный пакет не полон?

Эти вопросы пришли мне в голову, когда я подумал об упаковке веб-сокетов. Специальные символы используются для обозначения начала и конца пакета, что приводит к выводу о невозможности разделения нескольких пакетов.

P.S. Все вопросы касаются TCP / IP, но вы также можете поделиться информацией (ответами) о UDP.

Ответы [ 2 ]

2 голосов
/ 02 марта 2012

TCP сокеты основаны на потоке. Порядок гарантирован, но число байтов, которое вы получаете с каждым recv / read, может быть любым фрагментом ожидающих байтов от отправителя. Вы можете наложить транспорт на основе сообщений поверх TCP, добавив информацию кадрирования, чтобы указать способ, которым полезная нагрузка должна быть разбита на сообщения. Это то, что делает WebSockets. Каждое сообщение / фрейм WebSocket начинается не менее чем с 2 байтами информации заголовка, которая содержит длину полезной нагрузки, которая должна следовать. Это позволяет получателю ожидать и повторно собирать полные сообщения.

Например, для библиотек / интерфейсов, которые реализуют стандартный Websocket API или аналогичный API (например, браузер), событие onmessage будет запускаться один раз для каждого полученного сообщения, а атрибут данных события будет содержать все сообщение.

Обратите внимание, что в более ранней версии Hixie WebSockets каждый кадр начинался с '\ x00' и заканчивался '\ xff'. Текущая стандартизированная версия протокола IETF 6455 (HyBi) использует информацию заголовка, которая содержит длину, которая позволяет значительно упростить обработку кадров (но учтите, что и старый, и новый все еще основаны на сообщениях и имеют в основном один и тот же API). 1007 *

1 голос
/ 02 марта 2012

TCP-соединение обеспечивает поток байтов , поэтому рассматривайте его как таковой. Границы сообщений приложения не сохраняются - одна отправка может соответствовать нескольким получателям, а другая - наоборот. Вам нужны петли с обеих сторон.

UDP, с другой стороны, основан на дейтаграмме (то есть сообщении). Здесь одно чтение всегда удалит одну датаграмму из очереди (если только вы не возитесь с низкоуровневыми флагами на сокете). Событие, если буфер вашего приложения меньше ожидающей дейтаграммы и вы читаете только его часть, остальная часть теряется. Обходной путь - ограничить размер отправляемых дейтаграмм чем-то ниже обычного MTU, равного 1500 (меньше заголовков IP и UDP, поэтому фактически 1472).

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