Можно ли отправлять дейтаграммы по TCP? - PullRequest
2 голосов
/ 09 апреля 2010

Теоретически ничто не мешает использовать сокет TCP с SOCK_DGRAM. То, что вы получите, это надежный транспорт датаграмм. Возможно ли это с помощью розеток Беркли?

Ответы [ 6 ]

4 голосов
/ 10 апреля 2010

На что вы хотите взглянуть - это Протокол SCTP . Он предоставляет возможность отправлять дейтаграммы через надежное соединение в стиле TCP:

В отличие от TCP, SCTP может быть характеризуется как ориентированный на записи, Это означает, что он транспортирует данные с точки зрения сообщения, аналогично Протокол пользовательских дейтаграмм (UDP), так что группа байтов (сообщение), отправленная в одном операция передачи (запись) читать точно так же, как эта группа на приложение получателя. TCP это ориентированные на поток, транспортирующие потоки байтов, которые он правильно переупорядочивает в случае неупорядоченной доставки. Это однако, не соблюдает чести границы, то есть структура данные с точки зрения их оригинала блоки передачи у отправителя.

Взгляните на соединения типа «один к одному» по протоколу SCTP, которые, вероятно, вам нужны.

Существуют реализации для большинства ОС Unix / Linux и существует сторонняя реализация для Windows. Подробности смотрите в конце статьи Wiki, на которую я ссылался.

3 голосов
/ 09 апреля 2010

SOCK_DGRAM как тип получает вам сокет UDP. Конечно, вы можете инкапсулировать UDP в TCP, но вам придется обрабатывать часть UDP в пользовательском пространстве. Надежность чего-либо зависит от протокола на проводе. Если вы используете TCP, это надежно; UDP не.

Чтобы создать сокет UDP:

int s;
s = socket(AF_INET, SOCK_DGRAM, 0);

Чтобы создать сокет TCP:

int s;
s = socket(AF_INET, SOCK_STREAM, 0);

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

1 голос
/ 09 апреля 2010

Теоретически ничто не мешает использовать TCP-сокет с SOCK_DGRAM. То, что вы получите, это надежный транспорт датаграмм. Возможно ли это с помощью розеток Беркли?

Нет, API Беркли предоставляет ненадежную дейтаграмму или надежный поток.

Если вы хотите отправлять надежные порции по TCP, используйте некоторый протокол, который разбивает поток на порции. Это очень просто сделать.

0 голосов
/ 11 апреля 2010

Вы можете имитировать вещи, но на самом деле нет причин для этого. Либо вы хотите надежную доставку или вы хотите своевременную доставку. TCP дает вам первое, UDP дает второе. Эти два не могут смешаться, потому что TCP реализует надежность, постоянно сообщая другому концу о сообщениях, пока они не будут подтверждены. Для потоковой передачи обычно требуется надежная доставка данных (чтобы вы могли повторно собрать поток), но для небольших сообщений, где порядок не важен (например, дейтаграммы), вам не нужны все эти издержки (UDP в значительной степени гарантирует, что сообщения в по крайней мере не прибудет искаженным, это одна из вещей, которые TCP и UDP предлагают по сыром IP).

Есть, конечно, и другие интересные случаи между этими двумя крайностями. Для потоковой передачи данных в режиме реального времени (например, видеовызова) вы используете RTP , потому что вы используете потоковую передачу, но можете восстанавливаться после потери данных лучше, чем с задержкой. Для сообщений, которые слишком велики для UDP (64 КБ - это строгая верхняя граница, поскольку заголовок UDP имеет только 16 битов для своего поля длины), вам почти все равно нужно использовать TCP для транспорта, чтобы можно было повторно собрать фрагменты (следовательно, SOAP проходит через HTTP через TCP, а не через UDP).

0 голосов
/ 10 апреля 2010

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

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

0 голосов
/ 09 апреля 2010

Не совсем. TCP и UDP - это протоколы одного уровня, и они имеют функции, которые имеют смысл только для них. Возьмите listen () и accept (), например.

Вы можете отправлять UDP-заголовок + данные внутри TCP-пакетов, но это не имеет смысла. Почему ты бы так поступил? Вид туннелирования? На самом деле, анализировать и создавать UDP-пакеты очень легко вручную, но я не вижу реального приложения в вашем сценарии.

...