Может ли TCP отправлять сегменты меньшего размера, чем установленный максимальный (MSS/MTU)?

Предположим, сервер отправляет по TCP большой файл. У клиента размер приёмного окна равен 4000 байт (всё окно свободно), MSS — 1000 байт, а в буфере сервера доступно 6000 байт данных. Может ли TCP‑сервер отправить сегмент размером менее 1000 байт? Если да — в каких ситуациях это может произойти?
  • 19 июня 2026 г. 14:00
Ответы на вопрос 1
Коротко — да. MSS/MTU задаёт только верхнюю границу полезной нагрузки TCP‑сегмента, а не жёсткий размер каждого отправляемого сегмента. В вашем примере (rwnd=4000, MSS=1000, в буфере 6000) обычно можно отправить четыре полных сегмента по 1000 байт, но в ряде ситуаций TCP может отправить и меньшие сегменты. Основные случаи:

- Оставшиеся данные меньше MSS. Если в буфере осталось <1000 байт, финальный сегмент будет меньшим.  
  Пример: осталось 500 байт → сегмент 500 байт.

- Ограничение по cwnd (congestion window). TCP шлёт не больше min(cwnd, rwnd, данные). Если cwnd не кратно MSS или вообще меньше 4·MSS, последний допустимый сегмент может быть меньше MSS.  
  Пример: cwnd = 3500 → можно отправить 3×1000 и 1×500.

- Режим восстановления после потерь / частичные подтверждения. При fast recovery/partial ACK TCP может отправлять сегменты, размер которых соответствует освободившемуся «праву» на передачу — они могут быть неравны MSS.

- Малые записи приложения / политика сокета. Если приложение делает write() на <MSS байт и TCP решит немедленно передать (например, нет незакрытых данных, или отключён Nagle/TCP_NODELAY), отправится маленький сегмент.

- Nagle/Delayed ACK взаимодействие. Nagle старается избегать мелких сегментов, но при определённых условиях (нет несёмых неподтверждённых данных, или после получения ACK) маленький сегмент всё равно будет отправлен.

- Window‑probe (zero‑window probe). При закрытом окне отправляются маленькие (часто 1 байт) пакеты для проверки окна.

- FIN/закрытие соединения. FIN занимает номер последовательности и может быть отправлен вместе с небольшим количеством данных или отдельно в маленьком сегменте.

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

Примечание про TSO/GSO: сетевые драйверы/ничи могут агрегировать большие буферы и разбивать их на MSS‑слоты в NIC; это не отменяет того, что «на провода» пойдут сегменты не больше MSS, а последний фрагмент может быть меньше.

Итого: MSS — максимум, а не обязательный размер. Мелкие сегменты встречаются в ряде обычных ситуаций, особенно при ограничениях cwnd/rwnd, при остаточных данных, при работе механизмов управления (Nagle, recovery, window probe) или из‑за поведения приложения.
Похожие вопросы