2013-09-25 4 views
0

У меня есть тестовое приложение на C++ и C, где клиент постоянно бомбардирует сервер с последним номером, отправленным сервером, когда сервер получает один из этих пакетов, он несколько раз увеличивает число и затем отправляет новый номер в клиент, то, что происходит, клиент всегда 1 номер за сервером на локальном компьютере, на котором работают как клиент, так и сервер, что вполне ожидаемо.Windows/Winsock UDP-пакеты группируются вместе?

Это нормально, когда recvfrom и sendto ожидают и отправляют 9328 байт-пакетов, однако, когда я отбрасываю размер пакетов до 256, клиент всегда 33 раза синхронизируется, когда клиент отправляет 44-байтовый пакет, а сервер ожидает 256 байтов, клиент всегда 212 отсчитывает синхронизацию, каждый раз без сбоев на одном компьютере.

Я отправляю эти пакеты с использованием IP-адреса LAN, клиент и сервер находятся на одной машине, прослушивая через порты 3000 и 2000 соответственно.

Клиент отправляет пакеты на сервере так быстро, как только может. Сервер будет отправлять обновленный счет клиенту только при получении пакета.

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

Как отправить < 256 байтовых пакетов без этого? Я хочу избежать фрагментации пакетов, насколько это возможно во время поездки пакета, поэтому сохранение небольшого размера является требованием, когда оно входит и оставляет какое-то определенное оборудование.

+0

Можете ли вы показать какой-то код, относящийся к тому, где вы думаете, что проблема может быть скрыта? Это поможет устранить проблему. – ryyker

+0

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

+0

Драйвер устройства имеет внутренние буферы, которые объединяют пакеты вместе, поэтому да, установка буферов на 0 предотвратит это (и немного ускорит переходное время). Недостатком является более дорогое отправление в пакете и возможность пропустить пакеты, если вы не быстро достаточно. Чтобы ответить, просто добавьте ответ и примите его. – Serdalis

ответ

0

Эти три строки отключат буфер пакетов, установив его размер равным нулю.

const int size = 0; 
setsockopt(sd, SOL_SOCKET, SO_SNDBUF, (const char *)&size, sizeof(int)); 
setsockopt(sd, SOL_SOCKET, SO_RCVBUF, (const char *)&size, sizeof(int)); 

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

+0

Действительно ли это работает? Каков размер, возвращаемый функцией getsockopt(), когда вы это делаете? – EJP

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