Отправка данных переменной длины через сокет TCP - PullRequest
3 голосов
/ 07 сентября 2010

Мое приложение должно отправлять / получать данные XML через сокет TCP. Невозможно включить какой-либо заголовок фиксированной длины, содержащий длину сообщения. Насколько я понимаю, данные, передаваемые по tcp, могут поступать получателю вот так.

  1. GE> <содержание </p>

  2. > привет

Но почему-то этого никогда не происходит, что означает, что данные, отправленные с помощью одной операции Send () (при условии, что она короче или равна размеру буфера сокета), всегда полностью считываются с помощью одной операции Receive (). Возможен ли приведенный выше сценарий, учитывая, что буферы сокетов конечных точек достаточно велики и никогда не превышаются?

Ответы [ 3 ]

4 голосов
/ 07 сентября 2010

Да, это возможно.

Вы действительно не можете предполагать, что границы буфера в операции send () на одной стороне будут совпадать с границами, которые видны в соответствующем recv () на другом конце, даже если в большинстве случаев это происходит .

Например, если вы отправляете много данных, возможно, что принимающая ОС вызовет управление потоком TCP, а отправляющая ОС сможет отправлять только часть буфера. Или, может быть, базовая сеть имеет ограничение размера пакета, которое требует разделения вещей, или ...

1 голос
/ 07 сентября 2010

Это может легко произойти, если между ними есть прокси.Если мы предположим, что прокси не существует, клиент получит те же пакеты, что и сервер.Если вы отправляете данные кусками, меньшими, чем TCP MSS вашей ссылки, клиент, вероятно, получит их одним фрагментом.

Однако я бы не стал полагаться на это.Легко определить конец XML-сообщения, увидев тег закрытия (</message>), поэтому легко разобрать XML из потока.

0 голосов
/ 07 сентября 2010

Вы можете включить длину сообщения в ваши сообщения.Все, что вам нужно сделать, это, когда вы отправляете сообщение в формате xml, вы добавляете его с длиной сообщения в первых 4 байтах, а затем отправляете сообщение в формате XMLПри получении вы берете первые 4 байта потока в качестве длины сообщения, а затем читаете каждый байт для сообщения xml msg

...