Когда сетевой пакет TCP будет фрагментирован на прикладном уровне?

Вы можете взглянуть на CGI , который обеспечивает способ взаимодействия веб-сервера с исполняемым файлом через стандартный ввод и вывод. Существует также ответ о переполнении стека , в котором подробно описывается, что такое CGI. Для пользовательского ввода CGI может передавать данные в обоих направлениях, поэтому он должен быть способен к тому, чего вы пытаетесь достичь.

34
задан zooropa 16 April 2009 в 16:01
поделиться

10 ответов

Он будет разбит при попадании на сетевое устройство с более низким MTU, чем размер пакетов. Большинство устройств Ethernet имеют 1500, но часто могут быть меньше, 1492, если этот Ethernet переходит через PPPoE (DSL) из-за дополнительной информации о маршрутизации, даже ниже, если добавляется второй уровень, такой как Windows Internet Connection Sharing. И дозвон обычно составляет 576!

В общем, хотя вы должны помнить, что TCP не является пакетным протоколом . Он использует пакеты на самом низком уровне для передачи по IP, но с точки зрения интерфейса для любого стека TCP это потоковый протокол, и он не требует предоставления вам отношения 1: 1 к физическим пакетам, отправленным или полученным. (например, большинство стеков будет содержать сообщения до истечения определенного периода времени, или достаточно сообщений, чтобы максимизировать размер IP-пакета для данного MTU).

Например, если вы отправили два «пакета» (дважды вызовите функцию отправки), принимающая программа может получить только 1 «пакет» ( принимающий стек TCP может объединить их вместе). Если вы внедряете протокол типа сообщения через TCP, вы должны включить заголовок в начале каждого сообщения (или некоторый другой механизм заголовка / нижнего колонтитула), чтобы принимающая сторона могла разделить поток TCP обратно на отдельные сообщения, либо когда сообщение принимается в двух частях или когда несколько сообщений принимаются в виде чанка.

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

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

37
ответ дан 27 November 2019 в 16:26
поделиться

Фрагментация должна быть прозрачной для приложения TCP. Имейте в виду, что TCP является потоковым протоколом: вы получаете поток данных, а не пакеты! Если вы строите свое приложение, основываясь на идее полных пакетов данных, у вас будут проблемы, если вы не добавите уровень абстракции, чтобы собрать целые пакеты из потока, а затем передать пакеты приложению.

16
ответ дан 27 November 2019 в 16:26
поделиться

На прикладном уровне существует множество причин, по которым целые 1500 байтов могут не отображаться за одно чтение. Различные факторы во внутренней операционной системе и стеке TCP могут привести к тому, что приложение получит несколько байтов за один вызов чтения, а некоторые - в следующем. Да, стек TCP должен пересобрать пакет перед отправкой, но это не значит, что ваше приложение получит все это за один раз (скорее всего, он получит его за одно чтение, но это НЕ ГАРАНТИРУЕТСЯ получите его за одно чтение).

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

5
ответ дан 27 November 2019 в 16:26
поделиться

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

Восстановление пакета должно быть полностью прозрачным для приложений.

2
ответ дан 27 November 2019 в 16:26
поделиться

Разные сегменты сети могут иметь разные значения MTU. В этом случае может произойти фрагментация. Для получения дополнительной информации см. Максимальный размер сегмента TCP

. Эта (де) фрагментация происходит на уровне TCP. На прикладном уровне больше нет пакетов. TCP предоставляет приложению непрерывный поток данных.

2
ответ дан 27 November 2019 в 16:26
поделиться

Правильно - наиболее информативным способом увидеть это является использование Wireshark , бесценного инструмента. Потратьте время, чтобы понять это - несколько раз спасло меня и хорошо проверило реальность

1
ответ дан 27 November 2019 в 16:26
поделиться

Если 3000-байтовый пакет входит в сеть Ethernet с размером MTU по умолчанию 1500 (для Ethernet), он будет фрагментированы на два пакета по 1500 байт в длину. Это единственный раз, когда я могу вспомнить.

Wireshark - ваш лучший выбор для проверки этого. Я использую его некоторое время и полностью впечатлен

0
ответ дан 27 November 2019 в 16:26
поделиться

На "уровне приложения" пакет TCP (ну, на самом деле сегмент; TCP на своем собственном уровне не знает из пакетов) никогда не фрагментируется, поскольку его не существует. На прикладном уровне вы видите данные как поток байтов, доставленный надежно и упорядоченно.

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

2
ответ дан 27 November 2019 в 16:26
поделиться

В вопросе делается неверное предположение - TCP не доставляет пакеты своим конечным точкам, а отправляет поток байтов (октетов).Если приложение записывает две строки в TCP, они могут быть доставлены как одна строка на другом конце; аналогично, одна строка может быть доставлена ​​как две (или более) строки на другом конце.

RFC 793 , раздел 1.5:

«TCP может передавать непрерывный поток октетов в каждом направлении между своими пользователями путем упаковки. некоторое количество октетов в сегментах для передачи через интернет-систему . "

Ключевые слова - непрерывный поток октетов (байтов).

RFC 793 , раздел 2.8:

«Нет необходимой взаимосвязи между функциями push и границами сегмента. Данные в любом конкретном сегменте могут быть результатом одного вызова SEND, целиком или частично, или нескольких вызовов SEND ».

Раздел 2.8 полностью уместен.

11
ответ дан 27 November 2019 в 16:26
поделиться

Эта страница является хорошим источником информации о некоторых проблемах то, что подняли другие, а именно необходимость инкапсуляции данных в протоколе приложения на основе протокола приложения. Не совсем авторитетный в том смысле, который вы описываете, но в нем есть примеры, и он исходит от некоторых довольно крупных имен в сетевом программировании.

2
ответ дан 27 November 2019 в 16:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: