2008-11-03 11 views
5

У меня необычная ситуация: я использую систему Linux во встроенной ситуации (поле Intel, в настоящее время использующее ядро ​​2.6.20), которое должно взаимодействуют со встроенной системой, которая имеет частично нарушенную реализацию TCP. Насколько я могу сказать прямо сейчас, они ожидают, что каждое сообщение от нас появится в отдельном кадре Ethernet! У них, похоже, проблемы, когда сообщения разбиваются по Ethernet-кадрам.Мне нужна опция TCP (ioctl) для немедленной отправки данных

Мы находимся в локальной сети с устройством, и между нами нет маршрутизаторов (только переключатель).

Мы, конечно, пытаемся заставить их исправить свою систему, но это может оказаться невозможным.

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

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

Есть ли способ, которым я могу определить, имеет ли драйвер данные в очереди или нет? Есть ли способ заставить драйвер отправлять независимые вызовы записи в независимые пакеты транспортного уровня? Я просмотрел страницы сокетов (7) и tcp (7), и я ничего не нашел. Может быть, я не знаю, что я ищу.

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

Любая помощь очень ценится.

ответ

7

IIUC, устанавливающий параметр TCP_NODELAY, должен очищать все пакеты (т. Е. Tcp.c реализует настройку NODELAY с вызовом tcp_push_pending_frames). Поэтому, если вы установите параметр сокета после каждого вызова, вы должны получить то, что хотите.

1

Возможно, установите TCP_NODELAY и установите свой MTU достаточно низким, чтобы на 1 кадр было не более 1 сообщения? О, и добавьте флаг «dont-fragment» на исходящие пакеты

+0

Хорошая идея. К сожалению, поскольку сообщения не однородны по размеру, я не могу выбрать MTU, который обеспечивал бы одно сообщение на кадр в этом экземпляре. – 2008-11-03 16:41:26

0

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

+0

К сожалению, это вызовет больше проблем на другом конце, чем фрагментированные сообщения, поэтому в этом случае он не будет работать. – 2008-11-03 16:39:52

0

В худшем случае вы можете пойти на один уровень ниже (сырые сокеты), где у вас есть лучший контроль над отправленными пакетами, но тогда вам придется иметь дело со всеми nitty-gritty TCP.

-1

Может быть, вы могли бы попробовать положить стек ТСР в низкой латентностью режиме:

echo 1 > /proc/sys/net/ipv4/tcp_low_latency 

Это должно благоприятствовать испускать пакеты как можно быстрее через объединение данных. Прочтите человека на tcp (7) для получения дополнительной информации.

+0

Судя по коду в ядре Linux (net/ipv4/tcp.c), флаг tcp_low_latency влияет только на чтение данных из стека TCP в буфер приложения. – Alexander 2008-11-03 22:12:19

+0

Александр прав – 2012-12-06 08:48:06

2

Вы не можете решить проблему, если не уверены, в чем проблема.

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^