write() и накладные расходы TCP/IP

Если я пишу в файловый дескриптор сокета, используя write() байты за байтами,

  • Каждый байт теперь представляет собой пакет?
  • будет ли сокет добавлять заголовок TCP/IP к каждому байту?
  • Или у него есть буферный механизм (я лично в этом сомневаюсь, так как у меня нет явного сброса).

Например:

write(fd, 'a', 1);
write(fd, 'b', 1);
write(fd, 'c', 1);

Будет ли это менее эффективно, чем сказать

write (fd, 'abc', 3);
  • Я должен спросить об этом здесь, потому что у меня нет опыта для мониторинга заголовков TCP/IP в трафике. Спасибо.

person idunnolol    schedule 14.02.2011    source источник


Ответы (3)


Нет, не каждый байт станет пакетом. Некоторые могут быть объединены из-за алгоритма Нэгла и других вещей. Для каждого пакета будет один заголовок TCP, а не для каждого байта.

Тем не менее, вам следует избегать вызова записи/отправки байт за байтом, потому что каждый из них является системным вызовом, который является дорогостоящим (на локальной машине, а не с точки зрения того, как он попадает в сеть).

person John Zwinck    schedule 14.02.2011

Добавляя к ответу Джона, вы можете отключить алгоритм Нэгла (через TCP_NODELAY), и тогда первая версия станет медленнее.

И наоборот, вы можете вызвать writev() вместо write(), что приведет к тому, что первая версия будет работать точно так же, как вторая.

person chrisaycock    schedule 14.02.2011
comment
+1 за writev. Вы также можете использовать stdio с буферизованным FILE. - person R.. GitHub STOP HELPING ICE; 14.02.2011

Это действительно зависит от реализации стека TCP/IP. Это действительно будет зависеть от сегментации, реализованной в ОС. Большинство операционных систем уже имеют множество встроенных оптимизаций.

Если вы рассматриваете наихудший случай, заголовок TCP составляет 20 байтов, заголовок IP — 20 байтов, а размер заголовка кадра (в зависимости от используемого вами протокола, вероятно, Ethernet), поэтому вы можете ожидать, что плюс ваша полезная нагрузка. При этом в большей части трафика в Интернете преобладают ACK, однако ваш сетевой стек должен объединять полезные нагрузки.

person davidstites    schedule 14.02.2011
comment
Это также зависит от спецификации TCP/IP, которая по умолчанию предписывает такие операции, как алгоритм Nagle. - person user207421; 14.02.2011