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

197

Каков максимальный размер пакета для соединения TCP или как я могу получить максимальный размер пакета?

Alexa
источник
24
TCP основан на потоке. Есть ли конкретная причина, по которой вы беспокоитесь об отдельных пакетах?
Матти Вирккунен
27
Поскольку уровни ниже этого уровня основаны на пакетах ... Типичная реализация -> Уровень 1 - PHY Ethernet, Уровень 2 - MAC MAC Ethernet (определение пакета MAC, Уровень 3 - Протокол Интернета (определение пакета IP), Уровень 4 - TCP (Протокол управления передачей) ) - Использует пакетную службу под ним
2
Не существует такого понятия, как «пакет TCP». Существуют сегменты TCP , длина которых описана 32-битным словом, и они содержатся внутри или между IP- пакетами, длина которых описана в 16 битах. Есть также кадры Ethernet, которые содержат все эти вещи. О какой из этих вещей ты спрашиваешь? В любом случае, если вы используете TCP, вам не нужно беспокоиться ни о каком из них: TCP и IP позаботятся обо всем за вас.
Маркиз Лорн

Ответы:

178

Абсолютное ограничение на размер пакета TCP составляет 64 КБ (65535 байт), но на практике это намного больше, чем размер любого пакета, который вы увидите, потому что нижние уровни (например, Ethernet) имеют меньшие размеры пакетов.

MTU (максимальная единица передачи) для Ethernet, например, составляет 1500 байт. Некоторые типы сетей (например, Token Ring) имеют большие MTU, а некоторые типы имеют меньшие MTU, но значения фиксированы для каждой физической технологии.

простой эфир
источник
15
«Но значения фиксированы для каждой физической технологии» - это не так. Раньше максимальный MTU Ethernet был 1500, но вы можете использовать более низкий. С появлением гигантских кадров реального заданного максимума не существует, и этот максимум варьируется в зависимости от оборудования и драйвера.
WhirlWind
4
@Whirl: правда, они настраиваемы, но, как правило, это не так; «настраиваемый» субъективен, потому что для этого нужно вникать в ядро. Это не то, с чем можно повозиться на уровне приложения, где, как представляется, находится ОП.
эфир
3
@HiroProtagonist: 1500 - максимум, поэтому наличие 600 не удивительно.
Николас Рауль
30
почему ограничение 64 КБ (65535 байт)? Потому что атрибут размера окна в заголовке TCP составляет всего 16 бит. Я просто хотел упомянуть, может ли кто-нибудь когда-нибудь помочь ..... отличный ответ, кстати @Ether!
Cacho Santa
2
Кроме того, можно увеличить его с помощью масштабирования окна. В этом случае максимум составляет 1 ГиБ
Мартин Мелка
86

Это отличный вопрос, и я на самом деле много работаю над этим. Есть много «технически правильных» ответов, таких как 65k и 1500. Я много работал над написанием сетевых интерфейсов, и использование 65k глупо, а 1500 также может привести к большим неприятностям. Моя работа связана с большим количеством различного оборудования / платформ / маршрутизаторов, и, если честно, я начинаю с 1400 байт. Если вам НУЖНО больше 1400, вы можете начать продвигаться вверх, вероятно, вы можете перейти на 1450, а иногда и на 1480'ish? Если вам нужно больше, то, конечно, вам нужно разделить на 2 пакета, из которых есть несколько очевидных способов сделать ..

Проблема в том, что вы говорите о создании пакета данных и его записи через TCP, но, конечно, есть привязанные данные заголовка и т. Д., Поэтому у вас есть «багаж», который поднимает вас до 1500 или более ..., а также У многих аппаратных средств есть более низкие пределы.

Если вы «подтолкнете это», вы можете получить действительно странные вещи. Сокращенные данные, очевидно, или пропущенные данные, которые я видел редко. Поврежденные данные тоже редко, но, безусловно, случаются.

Нектарий
источник
Почему запросы GET составляют в среднем около 600 байт?
10
Вы имеете в виду 64К, а не 65К. Я не знаю, что вы имеете в виду под словом «место, где я начинаю - 1400 байт». Вам не нужно беспокоиться о размерах пакетов в TCP API. Он заботится об определении и соблюдении пути MTU. Нет причин, почему вы не можете написать 2G в одном, send()если это удобно.
маркиз Лорн
19
Твой 1480'ishдолжен быть 1460. Заголовок IP и заголовок TCP занимают не менее 20 байтов каждый (если не используются необязательные поля заголовка), и, таким образом, максимальный для (не Jumbo-кадра) Ethernet равен 1500 - 20 -20 = 1460.
Евгений Бересовский
2
Я видел через Wireshark, что сервер отправляет большие пакеты (более 1400 байт), и клиент получает его в разобранном виде, как несколько пакетов максимум 1400 байт. кто отвечает за разборку пакета? @Nektario ...?
Inbaly
2
@EugeneBeresovsky хорошо с дополнительными заголовками, которые + до 40 байт, но это переменная, поэтому 1420 может показаться ограничением. с предложением 1400 вы получаете небольшое дополнение. я пойду с 1408, так как он делится на 128
Гарет Клаборн
22

На уровне приложения приложение использует TCP в качестве потокового протокола. TCP, в свою очередь, имеет сегменты и абстрагирует детали работы с ненадежными IP-пакетами.

TCP имеет дело с сегментами вместо пакетов. Каждый сегмент TCP имеет порядковый номер, который содержится в заголовке TCP. Фактические данные, отправляемые в сегменте TCP, являются переменными.

Существует значение для getsockopt , которое поддерживается в некоторых ОС, которое вы можете использовать, называемое TCP_MAXSEG, которое извлекает максимальный размер сегмента TCP (MSS). Это не поддерживается на всех ОС, хотя.

Я не уверен, что именно вы пытаетесь сделать, но если вы хотите уменьшить размер используемого буфера, вы также можете посмотреть: SO_SNDBUF и SO_RCVBUF.

Брайан Р. Бонди
источник
Интересно, можно ли использовать TCP в качестве очереди сообщений, если вы можете поместить все свои сообщения в большой пакет TCP?
CMCDragonkai
4

В TCP API нет пакетов.

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

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

Павел Радзивиловский
источник
8
TCP имеет пакеты, а также заголовок пакета, часть которого перекрывает заголовок IP. То, что вы не должны видеть это, не означает, что его не существует. TCP всегда делается по IP. Вы не можете сделать это без IP, потому что заголовки перекрываются.
WhirlWind
23
У @WhirlWind TCP есть сегменты. У IP есть пакеты.
Маркиз Лорн
1
TCP имеет сегменты (или называете их пакетами, это нормально). TCP API не имеет пакетов.
Павел Радзивиловский
13
@NathanLong Вред в том, что вы вызываете ненужную путаницу. У TCP есть сегменты, у UDP есть датаграммы, у IP есть пакеты, у Ethernet есть кадры, ...
Маркиз Лорн
1
@Chexxor Итак, какой язык вы собираетесь использовать для описания сегментов TCP внутри IP-пакетов внутри фреймов Ethernet? Нет необходимости путать проблему, используя один и тот же термин для разных понятий, когда авторы этих вещей сталкиваются с большими трудностями при использовании разных терминов.
маркиз Лорн
3

Как правило, это будет зависеть от интерфейса, который использует соединение. Вероятно, вы можете использовать ioctl () для получения MTU, и, если это Ethernet, вы можете получить максимальный размер пакета, вычитая из этого размер аппаратного заголовка, который равен 14 для Ethernet без VLAN.

Это только в том случае, если MTU по крайней мере настолько велик по всей сети. TCP может использовать обнаружение MTU пути для уменьшения вашего эффективного MTU.

Вопрос в том, почему тебя это волнует?

Вихрь
источник
6
Это даст вам только максимальный размер пакета на первой ссылке. Насколько я знаю, любому другому узлу на маршруте разрешено не любить большие пакеты, и он может быть разбит в любом месте пути.
Матти Вирккунен
Да, это правда ... так что твой вопрос хорош - зачем тебе это?
WhirlWind
Я хочу передавать видео / изображения по локальной сети
Alexa
1
Так как TCP ориентирован на поток, почему это важно?
WhirlWind
3

Если вы работаете с Linux, «ifconfig eth0 mtu 9000 up» - это команда для установки MTU для интерфейса. Тем не менее, я должен сказать, что большой MTU имеет некоторые недостатки, если передача по сети не так стабильна, и он может использовать больше памяти пространства ядра.

DAG
источник
3

Кажется, что большинство веб-сайтов в Интернете используют 1460 байт для значения MTU. Иногда это 1452, и если вы используете VPN, для заголовков IPSec он будет еще больше.

Размер окна по умолчанию варьируется от 65535 байт. Я использую http://tcpcheck.com, чтобы посмотреть свои собственные значения IP-адреса и проверить, что используют другие интернет-поставщики.

Дэвид МакКаллох
источник
2

Одним из решений может быть установка опции сокета TCP_MAXSEG ( http://linux.die.net/man/7/tcp ) в значение, которое является «безопасным» для базовой сети (например, для 1400, чтобы быть безопасным для Ethernet), а затем использовать большой буфер при отправке системного вызова. Таким образом, может быть меньше системных вызовов, которые стоят дорого. Ядро разделит данные в соответствии с MSS.

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

hashtpaa
источник
2

Размер пакета для настройки TCP в протоколе IP (Ip4). Для этого поля (TL) выделено 16 битов, соответственно максимальный размер пакета составляет 65535 байтов: подробности протокола IP

Ziegfried
источник