Максимальный размер пакета TCP и UDP

При использовании recvfrom(2) для получения пакета из сети я получаю каждый раз 1 пакет.

Какова максимальная длина пакета TCP/UDP, получаемого с помощью этой функции?


person paramikoooo    schedule 10.02.2020    source источник
comment
TCP — это потоковый протокол, он не обрабатывает пакеты.   -  person Barmar    schedule 10.02.2020
comment
@Barmar Когда я использую recvfrom, я каждый раз получаю 1 пакет (как я вижу в wireshark)   -  person paramikoooo    schedule 10.02.2020
comment
IPv4 имеет 16-битное поле общего размера, что означает, что он может передавать до 65 535 байт. в одном пакете (включая заголовки и подпротокола).   -  person Some programmer dude    schedule 10.02.2020
comment
@paramikoooo Это не требование, это может быть связано с оптимизацией.   -  person Barmar    schedule 10.02.2020


Ответы (2)


В TCP нет фиксированного ограничения, потому что это потоковый протокол, а не протокол дейтаграмм.

В UDP через IPv4 ограничение составляет 65 507 байт. Из Википедии:

Длина
В этом поле указывается длина в байтах заголовка UDP и данных UDP. Минимальная длина 8 байт, длина заголовка. Размер поля устанавливает теоретический предел в 65 535 байт (8 байтов заголовка + 65 527 байтов данных) для дейтаграммы UDP. Однако фактическое ограничение на длину данных, налагаемое базовым протоколом IPv4, составляет 65 507 байт (65 535 — 8-байтовый заголовок UDP — 20-байтовый заголовок IP).

Используя jumbograms IPv6, можно получить дейтаграммы UDP размером более 65 535 байт. RFC 2675 указывает, что поле длины устанавливается равным нулю, если длина заголовка UDP плюс UDP данные больше 65 535.

Обратите внимание, что использование чрезвычайно больших дейтаграмм UDP может быть проблематичным. Немногие сетевые каналы имеют такие большие MTU, поэтому дейтаграмма, скорее всего, будет фрагментирована. Если какой-либо фрагмент потерян, уровень приложения должен будет повторно отправить всю дейтаграмму (если приложение требует и реализует надежность). TCP обычно использовал обнаружение MTU пути для отправки потока сегментами, которые соответствуют минимальному MTU всех ссылок на пути; если сегмент потерян, TCP может просто повторно передать сегменты после этого (или только потерянный сегмент, если реализовано выборочное подтверждение, которое сейчас предлагают большинство реализаций TCP).

person Barmar    schedule 10.02.2020
comment
Спасибо, добавил уточнение. - person Barmar; 10.02.2020

recvfrom всегда будет возвращать ровно один пакет для UDP. Пакеты UDP могут иметь размер до 64 КБ плюс-минус несколько байтов заголовка. На практике большинство протоколов UDP никогда не отправляют столько данных в одном пакете. Таким образом, размер вашего буфера, переданного в recvfrom, может быть намного меньше в зависимости от того, что диктует ваш протокол.

Для TCP вы обычно используете recv, а не recvfrom для чтения входящих данных из подключенного сокета. Многие укажут, что TCP — это потоковый протокол, а не протокол сообщений/пакетов, такой как UDP. Таким образом, recv вернет вам недетерминированное количество байтов между 1 и размером буфера, передаваемого самому вызову recv. Всегда проверяйте возвращаемое значение из вызова recv - это не гарантирует, что вы получите какое-либо конкретное количество байтов.

person selbie    schedule 10.02.2020
comment
могу ли я использовать recv для TCP и UDP? - person paramikoooo; 10.02.2020
comment
Относительно Для TCP обычно используется recv, а не recvfrom, правда, но только потому, что recv(sockfd, buf, len, flags) короче, чем эквивалентное recvfrom(sockfd, buf, len, flags, NULL, NULL) - person ikegami; 10.02.2020
comment
@paramikoooo, Re могу ли я использовать recv для TCP и UDP?, да. Для UDP это позволит любому отправлять дейтаграммы в сокет. Для TCP использование recv или read является нормой. - person ikegami; 10.02.2020
comment
IIRC любой может отправлять дейтаграммы в сокет UDP независимо от того, какую функцию вы используете. Но с recv вы не знаете, кто их послал. - person user253751; 10.02.2020