Отправка данных в отдельных сегментах TCP без объединения в стек TCP - PullRequest
2 голосов
/ 08 декабря 2011

В Linux (Kernel 3.0.0.12; C ++ с GCC 4.6.1) я хочу послать вскоре после друг друга несколько TCP-пакетов через (POSIX) send-call.

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

Можно ли как-то сказать системе отправлять данные из одного send() -буфера в собственныйTCP-пакет?Поток программы не должен блокироваться при отправке вызова.

Ответы [ 4 ]

9 голосов
/ 08 декабря 2011

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

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

  • Полный пакет данных доступен для отправки ИЛИ
  • Все ранее отправленные данные подтверждены получателем

Обычно это можно отключить, установив параметр сокета TCP_NODELAY.

setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
3 голосов
/ 08 декабря 2011

Вы можете отключить Nagle, но было бы лучше прекратить борьбу со стеком TCP. Лучше добавить некоторую форму кадрирования к вашему протоколу, так что вам не нужно беспокоиться о том, были ли ваши блоки передачи агрегированы и / или разделены.

В отправителе это обычно означает использование символов завершения или указание длины.

В приемнике это означает знание, как прочитать до некоторого символа завершения, и / или знание, как использовать часть полученного блока передачи или собрать полное сообщение из нескольких блоков передачи.

Мне нравится делать это с bufsock, хотя это очень технология Python. Но вы, вероятно, хотите что-то подобное для C ++: http://stromberg.dnsalias.org/~strombrg/bufsock.html

3 голосов
/ 08 декабря 2011

Если вы хотите, чтобы каждый пакет отправлялся индивидуально, рассмотрите возможность использования UDP.Однако вам придется реализовать собственное обнаружение ошибок и повторную передачу отброшенных пакетов и т.д ...

1 голос
/ 08 декабря 2011

"пакет".

И нет, в этом весь смысл наличия * сетевого стека - ваши кадры Ethernet могут передаваться и маршрутизироваться независимо от более высоких уровней стека TCP / IP . Вы совершенно НЕ ХОТИТЕ микро-управлять этим!

...