Отправка TCP кадров фиксированной длины - PullRequest
5 голосов
/ 31 мая 2011

Мне нужно отправить некоторые данные через подсеть с фиксированным нестандартным MTU (например, 1560) с использованием TCP. Все кадры Ethernet, передаваемые через эту подсеть, должны заполняться вручную нулями, если длина кадра меньше MTU.

Итак, размер данных должен быть (1560 - sizeof (заголовок IP) - sizeof (заголовок TCP)).

Вот как я собираюсь это сделать:

  1. Я установил опцию TCP_CORK, чтобы уменьшить фрагментацию данных. Это ненадежно, потому что потолок 200 миллисекунд, но он работает.

  2. Я знаю размер IP-заголовка (20 байтов), поэтому длина данных должна быть равна (1540 - sizeof (TCP-заголовок)).

  3. В этом проблема. Я не знаю размер заголовка TCP. Размер поля «Опции» является плавающим.

Итак, вопрос: как получить размер заголовка TCP? Или, может быть, есть какой-то способ отправки фреймов TCP с заголовками фиксированной длины?

Ответы [ 4 ]

10 голосов
/ 31 мая 2011

Попытка контролировать размер кадров при использовании TCP из пользовательского приложения неверна. Вы работаете на неправильном уровне абстракции. Это также невозможно.

Вам следует либо заменить TCP на что-то другое (UDP?), Либо, что менее вероятно, но возможно, переписать свой драйвер Ethernet, чтобы установить нестандартный MTU и выполнить необходимое заполнение.

6 голосов
/ 31 мая 2011

Это невозможно при использовании стека TCP хоста просто потому, что стек TCP, следующий за RFC 793, не должен предоставлять такой вид доступа к приложению.

То есть, нетt (и не должно быть) способ повлиять на то, что нижние уровни делают с вашими данными.Конечно, есть способы повлиять на то, что делает TCP (например, Нэгл), но это противоречит духу протокола.TCP следует использовать для достижения наилучших результатов: для передачи непрерывного упорядоченного потока байтов.Ни больше ни меньше.Нет сообщений, пакетов, фреймов.

Если в конце концов вам нужно контролировать эти детали, вам нужно взглянуть на API более низкого уровня.Вы можете использовать SOCK_RAW и PF_PACKET.

Пакетные сокеты используются для приема или отправки необработанных пакетов на уровне драйвера устройства (уровень 2 OSI).

@gby упомянул UDP, и это (частично) хорошая идея: UDP имеет фиксированный размер.Но имейте в виду, что вам придется иметь дело с фрагментацией IP (или использовать IP_DONTFRAG).

2 голосов
/ 31 мая 2011

В дополнение к моим комментариям, приведенным ниже к вопросу OP, актуальна эта цитата из оригинального RFC, в которой указано, как отправлять TCP / IP через Ethernet:

RFC 894 (выделеномой): При необходимости, поле данных должно быть заполнено (с октетами ноль), чтобы соответствовать Ethernet минимальный размер кадра .

Если они хотели, чтобы все кадры Ethernet были намаксимальный размер, они бы так сказали.Они этого не сделали.

0 голосов
/ 29 апреля 2015

Может быть, то, что подразумевалось под отступом, это то, что заполнение заголовка TCP для его выравнивания по 32 битам должно иметь все нули: http://freesoft.org/CIE/Course/Section4/8.htm

...