Вопрос

Я читал различные сайты и учебные пособия в Интернете, но я все еще запутался. Если сообщение больше IP MTU, то send() Возвращает отправленный байт. Что происходит с остальной частью сообщения? Я позвонил send() Снова и пытаетесь отправить остальную часть сообщения? Или это то, что IP -слой должен позаботиться автоматически?

Это было полезно?

Решение

Если вы используете TCP, то представленное вам интерфейс - это поток байтов. Вам не нужно беспокоиться о том, как поток байтов попадает от одного конца соединения с другим. Вы можете игнорировать MTU IP -слоя. На самом деле вы можете полностью игнорировать IP -слой.

Когда вы звоните send() Стек TCP на вашей машине будет иметь дело со всеми деталями, необходимыми для потока байтов, которые вы вносите в свои вызовы отправки, чтобы появиться из recv() вызовы на другом конце соединения.

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

Поскольку комментаторы попросили об этом;)

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

В любом случае, если send() Возвращает меньше, чем количество байтов, которые вы его поставили, тогда вы должны в какой -то момент отправить оставшиеся данные. Часто send() Заблокирует и подождет, пока он не сможет отправить все данные, и если вы установите розетку в режим не блокировки, вы, вероятно, не хотите немедленно повторно повторить отправку, если он не удастся отправить все, так как вы, вероятно, окажетесь в плотная петля ...

Вероятно, было бы полезно быть более конкретным в отношении операционной системы, которую вы используете.

Другие советы

Если пакет слишком велик, чтобы транзит сети, подсказка фрагментации ICMP отправляет сигнализацию отправителю, чтобы уменьшить размер пакета, и повторите попытку.

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

WRT UDP Вы все еще можете ожидать, что стек будет фрагментом для вас, но практически учитывая вариант использования для UDP, он не идеален.

... На вопросе Send () Некоторые стеки ведут себя по -разному, но лечение ваш код должен быть таким же. Допустим, у вас есть 100 байтов для отправки ... Send () возврата 10 байт отправлены. Вы должны продолжать звонить в отправку с оставшимися 90 байтами, пока все не вытолкнуло провод, чтобы отправить все сообщение.

Использование блокирующих розетков на платформе Windows Send () будет возвращаться после того, как все будет отправлено .. на других платформах. Linux et al. Вам нужно будет продолжать отправлять чаще для нажимания данных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top