powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
74 сообщений из 74, показаны все 3 страниц
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38583710
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Делаю UDP сервер. Работать будет в инете. В основном будет работать с одиночными сообщениями: принял, проверил, переслал/ответил. Тут все ясно.

Но будут такие ситуации когда целый поток сообщений. Тестил отправку залпом 1000 пакетов по 1000 байт по разным каналам. В некоторых случаях потеря до 90%. Правда не понял где именно теряется: у отправителя или получателя, т.е. не отправляются или не доходят.

1. Ломаю голову как организовать максимально быструю доставку: с одной стороны если слать по одному, то все доходят, но скорость передачи низкая, если слать залпом все и досылать потерянное тоже медленно т.к. 90% теряется.
Пока пришел к варианту слать пачками по 50-70 пакетов и получать подтверждение.
Наверняка готовые стратегии передачи есть , буду рад советам и ссылкам на эту тему.

2. Для минимизации потерь на входе хочу максимально ускорить получение разделив на отдельные потоки прием и отправку.
хочу сделать примерно так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
SOCKET sock;
typedef struct {
  int state;
  char buf[1000];
} msg_t;
msg_t msg[1000]; // буфера для приема сообщений

void read_thread()
{
 while(true) {
   size = recvfrom(sock, msg[i].buf, 1000, ...); // приняли
   msg[i].state = NEED_PARSE; // пометили на обработку
   i = (i + 1) % 1000; // берем следующий буфер
 }
}

void parse_thread()
{
 while(true) {
  for(int i = 0; i < 1000) {
     if(msg[i].state == NEED_PARSE) {
       ... обработка
       sendto(sock, ...); // отправка
       msg[i].state = FREE;
     }
  }
 }
}

int main()
{
 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 bind(sock, ...);
 _beginthread(parse_thread, ....);
 read_thread();
}


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

Т.е. поток чтения только принимает и помещает принятое в память, поток обработки разбирает сообщения и при необходимости что-то отправляет.
Тут возникает вопрос: Можно так использовать сокет в разных потоках? Т.е. один только принимает, второй только шлет.

Также интересны мнения даст ли такая схема хоть какие-то преимущества на однопроцессорной виртуалке по сравнению с "принял / обработал / отправил", если "обработал" это быстрые операции (проверка структуры, отправителя и т.п.).
принял / обработал / отправил
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
int main()
{
 SOCKET sock;
 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 bind(sock, ...);
 while(true) {
  char buf[1000];
   size = recvfrom(sock, buf, 1000, ...); // принял
   ... обработка
   sendto(sock, ...); // отправил
 }
}


И еще один ламерский вопрос: если я читаю по 1000 байт и прилетит пакет большего размера, то что произойдет? Я надеюсь что он просто удалится и ко мне не попадет.

PS Работать все будет в линуксовой виртуалке на хостинге. Клиенты на виндовсе.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38583824
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПока пришел к варианту слать пачками по 50-70 пакетов и получать подтверждение.
Так юзайте TCP, раз вы можете так сходу менять протокол :)

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

Проверить что просиходит с пакетами можно командой netstat -su на обоих хостах которая покажет статистику по UDP пакетам.
Dima Tесли я читаю по 1000 байт и прилетит пакет большего размера, то что произойдет? Я надеюсь что он просто удалится и ко мне не попадет.
Если прилетит больший пакет, то вы прочтете запрошенный размер, а остальное удалится. Т.е. следующее чтение прочтет следующий пакет, а не остаток предыдущего.
По крайней мере в линуксе так.
Dima T Можно так использовать сокет в разных потоках?
В теории можно, но я нигде не видел в доках явного разрешения (правда особо и не искал :)).
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38583825
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПока пришел к варианту слать пачками по 50-70 пакетов и получать подтверждение.
Наверняка готовые стратегии передачи есть, буду рад советам и ссылкам на эту тему.

Есть: TCP шлёт пакетов на размер окна без подтверждения, потом получает подтверждение на
всю пачку.

Dima TТут возникает вопрос: Можно так использовать сокет в разных потоках? Т.е.
один только принимает, второй только шлет.
Можно.

Dima TИ еще один ламерский вопрос: если я читаю по 1000 байт и прилетит пакет
большего размера, то что произойдет? Я надеюсь что он просто удалится и ко мне не
попадет.
Такой пакет просто не сможет отправиться. UDP пакеты ограничены ЕМНИП 256 байтами или даже
меньше.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38583837
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, забыл самое главное.

Как бы вы не старались, избежать потерь в UDP нельзя.
Поэтому если ваше приложение не допускает потерь, то вам нужен другой протокол доставки.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38583847
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovакой пакет просто не сможет отправиться. UDP пакеты ограничены ЕМНИП 256 байтами или даже
меньше.
Нет, нет такого лимита.
Лимит - это MTU сетевухи либо если включен discovery то MTU пути - стандартный лимит для IP протоколов.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38583872
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyНет, нет такого лимита.
Да, действительно, такого лимита нет.

MSDNFor message-oriented sockets, care must be taken not to exceed the maximum
packet size of the underlying subnets, which can be obtained by using getsockopt to
retrieve the value of socket option SO_MAX_MSG_SIZE. If the data is too long to pass
atomically through the underlying protocol, the error WSAEMSGSIZE is returned and no data
is transmitted.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38583918
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TДелаю UDP сервер. ...

Но будут такие ситуации когда целый поток сообщений. Тестил отправку залпом 1000 пакетов по 1000 байт по разным каналам. В некоторых случаях потеря до 90%. Правда не понял где именно теряется: у отправителя или получателя, т.е. не отправляются или не доходят.


Ты вообще в курсе, что UDP не гарантирует доставку сообщений ?
За что боролся, на то и напоролся. Где они теряются -- в принципе, не важно.

Dima T1. Ломаю голову как организовать максимально быструю доставку: с одной стороны если слать по одному, то все доходят, но скорость передачи низкая, если слать залпом все и досылать потерянное тоже медленно т.к. 90% теряется.
Пока пришел к варианту слать пачками по 50-70 пакетов и получать подтверждение.
Наверняка готовые стратегии передачи есть , буду рад советам и ссылкам на эту тему.


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

Dima TТут возникает вопрос: Можно так использовать сокет в разных потоках? Т.е. один только принимает, второй только шлет.


Э... сложный вопрос.

Dima TИ еще один ламерский вопрос: если я читаю по 1000 байт и прилетит пакет большего размера, то что произойдет? Я надеюсь что он просто удалится и ко мне не попадет.


Будет обрезан, но в общем случае читай man по функции, которую используешь.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38583932
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyDima TПока пришел к варианту слать пачками по 50-70 пакетов и получать подтверждение.
Так юзайте TCP, раз вы можете так сходу менять протокол :)
Понятно что в TCP уже есть то что надо, сначала его и думал использовать, даже boost asio поизучал и другие либы кросплатформенные.
У UDP есть большие плюсы:
1. UDP сервер может упасть, перегрузиться, а клиент это даже не заметит, решит что потери в сети.
2. Можно использовать несколько UDP серверов одновременно (при наличии синхронизации между ними)
3. По UDP элементарно делается p2p обмен между клиентами за роутерами (проверял из-за двух DLink`ов без какой либо доп. настроек): оба клиента постучались на сервер, сервер сообщил обоим клиентам адреса откуда они ему шлют (котырые НАТ дал), а дальше они друг-другу, сервер не нужен. TCP такое не позволит. Ради p2p стоит поизобретать свой аналог TCP. Тем более что у меня за раз пролетает 200 кб максимум.

Anatoly MoskovskyЗадать побольше буфер для UDP сокета.
setsockopt(SO_RCVBUF) оно?

Anatoly MoskovskyЕсли прилетит больший пакет, то вы прочтете запрошенный размер, а остальное удалится. Т.е. следующее чтение прочтет следующий пакет, а не остаток предыдущего.
По крайней мере в линуксе так.
Такое поведение устраивает. Главное чтоб за пределы буфера не вылез и прием не застопорил.

Anatoly MoskovskyDima T Можно так использовать сокет в разных потоках?
В теории можно, но я нигде не видел в доках явного разрешения (правда особо и не искал :)).
Все больше склоняюсь к тому что надо как можно быстрее принимать если есть что принимать, т.к. скорость приема критична.
Придумал еще один однопоточный вариант с select()
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
SOCKET sock;
typedef struct {
  int state;
  char buf[1000];
} msg_t;

int main()
{
 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 bind(sock, ...);
 msg_t msg[1000]; // буфера для приема сообщений
 while(true) {
   if(select(sock ... 0 сек)) {// проверка наличия входящих с таймаутом 0 сек
     size = recvfrom(sock, msg[i].buf, 1000, ...); // приняли
     msg[i].state = NEED_PARSE; // пометили на обработку
     i = (i + 1) % 1000; // берем следующий буфер
   } else {
     for(int i = 0; i < 1000) {
        if(msg[i].state == NEED_PARSE) {
          ... обработка
          sendto(sock, ...); // отправка по одному пока принимать нечего
          msg[i].state = FREE;
          break;
        }
   }
 }
}


тут единственный минус по сравнению с многопоточным в том что добавляется select() для проверки входящих, но думаю он особо не должен тормозить. Может такая схема даже лучше, чтобы вылетающие пакеты не сбивали влетающие )))
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38583993
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivТы вообще в курсе, что UDP не гарантирует доставку сообщений ?
За что боролся, на то и напоролся. Где они теряются -- в принципе, не важно.
В курсе, вот и спросил как минимизировать потери.
Я не за потери переживаю, а за трафик, он бесплатный до определенного предела, у многих хостеров в тарифах 20-25Гб в месяц бесплатно, а дальше особые условия с конскими ценами. Да и клиенты у меня есть на помегабайтных тарифах. Так что терять 90% трафика по дороге вообще не вариант. Надо 3-5%, не больше.
И вторая проблема с очень медленными каналами типа 3G с плохим приемом, там потери - это лишние перезапросы потерянного, т.е. доп.тормоза.
Вобщем надо как-то и терять поменьше и слать побыстрее.

Dima TАбстрактно задачу решать я считаю не имеет смысла -- нужно решать в рамках предметной области.
Задача очень даже не абстрактная. Мегабайт я с запасом взял, надо гонять файлы от 10 до 200 кб. И короткие сообщения меньше килобайта.

Буду изобретать алгоритм, чтоб и в гигабитной локалке и в GPRSе максимум скорости был.

Anatoly MoskovskyНет, нет такого лимита.
Лимит - это MTU сетевухи либо если включен discovery то MTU пути - стандартный лимит для IP протоколов.
Максимум размер UDP 65507 байт. Больше не отправляется.
Тесты показали что пакеты 65507 байт проходят до сервера в инете, но очень часто теряются. Зависит от типа подключения к инету. Например через L2TP подключение с MTU 1400 долетают до сервера, но на обратном пути рубится. С L2TP максимум 1372 байта (1400 -8 (заголовок IP) - 20 (заголовок UDP)), т.е. 1372 проходят, а 1373 уже больше половины теряется.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584023
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Торренты используют UDP http://habrahabr.ru/post/68332/
Есть описание протокола, буду изучать http://www.bittorrent.org/beps/bep_0029.html
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584160
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TУ UDP есть большие плюсы:
1. UDP сервер может упасть, перегрузиться, а клиент это даже не заметит, решит что потери в сети.
2. Можно использовать несколько UDP серверов одновременно (при наличии синхронизации между ними)
3. По UDP элементарно делается p2p обмен между клиентами за роутерами (проверял из-за двух DLink`ов без какой либо доп. настроек): оба клиента постучались на сервер, сервер сообщил обоим клиентам адреса откуда они ему шлют (котырые НАТ дал), а дальше они друг-другу, сервер не нужен. TCP такое не позволит. Ради p2p стоит поизобретать свой аналог TCP. Тем более что у меня за раз пролетает 200 кб максимум.А теперь внимательно читаем спецификацию HTTP/1.x и понимаем, что всё вышеизложенное может быть реализовано даже в рамках этого высокоуровнего протокола. Который проходит не только через NAT, но и, что важнее, через HTTP-прокси.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584192
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПо UDP элементарно делается p2p обмен между клиентами за роутерами (проверял
из-за двух DLink`ов без какой либо доп. настроек)
Это тебе просто сказочно повезло с твоими д-линками.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584221
locked
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry SibiryakovDima TПо UDP элементарно делается p2p обмен между клиентами за роутерами (проверял
из-за двух DLink`ов без какой либо доп. настроек)
Это тебе просто сказочно повезло с твоими д-линками.

нет, это известная техника. Как по твоему работает Скайп?
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584234
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lockedКак по твоему работает Скайп?Использует или "добрые души", которые разрешают входящие соединения для всякой всячины или (какое-то количество) "собственных" серверов.
Чудес не бывает.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584257
locked
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. Sidorov (какое-то количество) "собственных" серверов.
Чудес не бывает.
Эти "собственные сервера" только инициируют соединения. Весь медиа поток идет p2p.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584271
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovDima TПо UDP элементарно делается p2p обмен между клиентами за роутерами (проверял
из-за двух DLink`ов без какой либо доп. настроек)
Это тебе просто сказочно повезло с твоими д-линками.

Ну так у меня пользователи в основном с подобным железом.
В локалке тестил: виндовый брандмауэр тоже пропустил (сокет был с адресом 0:0, т.е. на усмотрение ОС). 7-ка с дефолтными настройками даже не спросила чего это у вас там шлется.
Допишу сервер, сделаю тестового клиента, устрою глобальный тест, тогда будет видно кто из клиентов сможет p2p работать, даже если половина - уже отлично.

Хотя подозреваю что большинство (у кого дефолтные настройки натов без доп.запретов) будет работать, т.к. принципы UDP ната таковы что делается связка localIP:port <-> natIP:port если внешний порт постоянный (natIP:port) при отправке по разным адресам, а он скорее всего постоянный т.к. иначе портов не напасешься если клиент начнет слать куче получателей, то дальше можно пробить даже продвинутые наты (помнящие куда клиент обращался) - для этого достаточно чтобы оба клиента послали по пакету навстречу друг-другу.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584339
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВ локалке тестил: виндовый брандмауэр тоже пропустил (сокет был с адресом
0:0, т.е. на усмотрение ОС). 7-ка с дефолтными настройками даже не спросила чего это у вас
там шлется.
Вот только не все провайдеры ткие пофигисты.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584398
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lockedЭти "собственные сервера" только инициируют соединения. Весь медиа поток идет p2p.Во-первых - я не просто так употребил союз "или".
Во-вторых - пофигистов много и (только) это позволяет существовать скайпу.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584425
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TAnatoly MoskovskyЗадать побольше буфер для UDP сокета.
setsockopt(SO_RCVBUF) оно?


Пробовали делать на принимающей стороне?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 // Установка размера.
  int size_write = (1024*100) ;
  if ( setsockopt ( UDP_s,
                    SOL_SOCKET,
                    SO_RCVBUF,
                    &size_write,
                    sizeof(size_write)
                   ) == -1 )


Проблему решило?

Пробовали увеличить MTU?
У себя в программе собирать несколько пакетов в один массив, передавать его, а на той стороне разбирать его?
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584444
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovВот только не все провайдеры ткие пофигисты.

Что значит пофигисты? Вопрос уходит за рамки темы в сторону моральных/этических/юридических/политических особенностей предоставления услуг. Тут выше упомянутая ссылка на скайп порадовала. Какой провайдер будет вводить ограничения мешающие работе скайпа? Наверно тот которому хочется избавится от немногих оставшихся клиентов.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584480
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинПроблему решило?
попробую когда сервер допишу.
Вася УткинПробовали увеличить MTU?
Это не наш путь. Все должно работать с имеющимися настройками. Все изменения нстроек должны быть только внутри собственного софта, т.е. отправителя и получателя.
Вася УткинУ себя в программе собирать несколько пакетов в один массив, передавать его, а на той стороне разбирать его?
Если быстро слать кусками по килобайту - доходит очень мало на медленных каналах. Описание протокола торрентов подсказало куда двигаться. У меня складывается мнение что надо изобретать какой-то эвристический алгоритм автоподстройки таймаутов отправки пакетов. Примерно так: послать 50 пакетов, подождать 300 мс, слать следующие 50 пакетов, в это время получить отчет о доставке первых 50-ти, поменять таймаут или количество отправляемое за раз. Т.к. у меня не торренты по несколько гигов, то задача усложняется, т.к. надо подстроится во время отправки 200 кб. Хотя можно не заморачиваться и слать по 20-30 пакетов и дожидаться подтверждения "медленно, но верно".
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584489
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКакой провайдер будет вводить ограничения мешающие работе скайпа?

1) Любой мобильный провайдер
2) Любой провайдер, садящий клиентов за собственный NAT
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584496
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если кому интерсно. В итоге решил остановиться на компромиссном однопоточном варианте с select() и приоритетом чтению.
однопоточный вариант с select()
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
SOCKET sock;
typedef struct {
  int state;
  char buf[1000];
} msg_t;

int main()
{
 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 bind(sock, ...);
 msg_t msg[1000]; // буфера для приема сообщений
 while(true) {
   if(select(sock ... 0 сек)) {// проверка наличия входящих с таймаутом 0 сек
     size = recvfrom(sock, msg[i].buf, 1000, ...); // приняли
     msg[i].state = NEED_PARSE; // пометили на обработку
     i = (i + 1) % 1000; // берем следующий буфер
   } else {
     for(int i = 0; i < 1000) {
        if(msg[i].state == NEED_PARSE) {
          ... обработка
          sendto(sock, ...); // отправка по одному пока принимать нечего
          msg[i].state = FREE;
          break;
        }
   }
 }
}


Лично мне с многопоточностью только доп.гимор при отладке.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584511
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovDima TКакой провайдер будет вводить ограничения мешающие работе скайпа?

1) Любой мобильный провайдер
Как выше писал тест по GPRS (включил WiFi роутер на телефоне, а связь не 3G) показал что канал очень сильно забивается и много потерь, особенно на больших пакетах (> 6000 байт), но из-за убогости сервера не смог померить реальную скорость. Сложно мерить то чего нет. Допишу, буду оптимизировать. В любом случае именно этот канал буду использовать для заточки на скорость, т.к. можно очень медленно передавать 200 кб по гигабитной сетке и никто это не заметит.
Dimitry Sibiryakov2) Любой провайдер, садящий клиентов за собственный NAT

Это п.1, а как обойти NAT я выше написал.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584512
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
Перед изобретением велосипеда, стоит посмотреть на работы предков.

http://www.amazon.com/gp/product/0132856204/ref=oh_details_o06_s01_i00?ie=UTF8&psc=1
Вполне неплохо описаны все основные принципы построения сетей. В том числе даны и алгоритмы организации сетевых протоколов.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584516
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tкак обойти NAT я выше написал.
Хрен ты провайдерский NAT обойдёшь. Он работает в паре с файерволлом (на котором,
собственно, и построен).
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584524
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovDima Tкак обойти NAT я выше написал.
Хрен ты провайдерский NAT обойдёшь. Он работает в паре с файерволлом (на котором,
собственно, и построен).
Не надо утверждать что провайдерский NAT нельзя пройти. Это в первую очередь зависит от провайдера и от ума того кто пытается пройти.

И вообще, NAT'ы они разные бывают. Так же как и файрволлы. Которые кстати, обычно построены на основе NAT принципов.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584537
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovDima Tкак обойти NAT я выше написал.
Хрен ты провайдерский NAT обойдёшь. Он работает в паре с файерволлом (на котором,
собственно, и построен).

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

Пофиг так-то, там где технические меры не помогут - задействую экономические. Объясню клиенту что провайдер у него ниочем и приведу в пример другого клиента с другим провайдером. Владельцы бизнеса хорошо понимают когда им говоришь что ты тут экономишь пару сотен рублей на интернете, а теряешь тысячи, особенно если привести в пример конкурента у которого сервис работает по-максимуму. Хотя есть трудные: один принципиально сидит на диалапе только чтоб никто в рабочее время в соцсети не лазил.

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

Лично мое мнение за p2p и UDP будущее. Сейчас активно развиваются сервисы по передаче видео, а это гигантский поток. Взять тот же SmartTV, который по сути интернет в телевизоре. Слать каждому зрителю то что он хочет смотреть нереально, посчитаем: среднепожатый HD фильм 4-5 Гб на 100 минут видео, т.е. 4000 / 100 / 60 * 8 ~ 5,5 мбит потока полезной инфы плюс заголовки пакетов будет все 6 мбит/сек и это на 1 (одного) пользователя, а для нормального бизнеса надо миллион пользователей, т.е. 6 террабит/сек., да ни один канал такого потока не выдержит. А тут есть p2p (которое вроде как и пользуют) позволяющее размазать трафик по клиентам, т.к. они смотрят не миллион разных фильмов, а гораздо меньше, но разные места фильма.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38584555
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

посмотрите в сторону SCTP. Это усовершенствованный TCP, и по все видимости заменит его в будущем, непоточный (ориентирован на сообщения), многоканальный (при недоступности одного канала сообщение будет послано через другой в рамках одного подключения) - multihoming, лучше защищен от DOS атак.

В линуксе реализация уже включена в ядро, для винды есть платные драйвера.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38585546
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЧто ж за упорство такое мое начинание обгадитьЧто за упорство такое смотреть на мир через розовые очки?Зачем провайдеру умышленно гадить своему клиенту?"Ничего криминального - только бизнес".
Некто собрался зарабатывать на мне деньги. Мои деньги. Не вопрос, но не надо ждать, что такому ушлому бизнесмену будет открыть зелёный свет.В общем тесты на клиентах покажут на что рассчитывать, хотя теория и тесты уже вдохновляютС "хорошей" теорией и "правильными" тестами - всегда так.Лично мое мнение за p2p и UDP будущееНу-ну ... Вот сейчас все выйдут из сумрака и начнётся всеобщее благоденствие ...
Requirements for Internet Hosts полезно почитать. Про автономные системы - тоже невредно знать. Чтобы начать осознавать разницу между реальной жизнью и локальной сетью или парочкой D-Link-ов.~ 5,5 мбит потока полезной инфы плюс заголовки пакетов будет все 6 мбит/сек и это на 1 (одного) пользователяКонечно, отображение (аппаратного) мультикастинга на IP-стек и управление членством в мультикаст-группе идиоты делали ...
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38585659
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovDima TЧто ж за упорство такое мое начинание обгадитьЧто за упорство такое смотреть на мир через розовые очки?
Причем тут очки? Конкретных фактов не приведено, есть просто общий скепсис опытных разработчиков по отношению к моей задумке. Это нормально, я так же отношусь к чужим "гениальным" идеям. Я не ожидаю встречного восторга от моего велосипеда с квадратными колесами. Но квадратные колеса имеют свои плюсы при езде по пилообразной дороге :)

Basil A. SidorovЗачем провайдеру умышленно гадить своему клиенту?"Ничего криминального - только бизнес".
Некто собрался зарабатывать на мне деньги. Мои деньги. Не вопрос, но не надо ждать, что такому ушлому бизнесмену будет открыть зелёный свет.
Теории заговоров оффтоп для данного форума. Не хочу спорить какова доля правды в данном утверждении.

Basil A. SidorovВ общем тесты на клиентах покажут на что рассчитывать, хотя теория и тесты уже вдохновляютС "хорошей" теорией и "правильными" тестами - всегда так.
Пока проведены предварительные тесты, которые говорят что надо писать. Пишу. Как допишу проведу тесты на всех своих клиентах. Тогда и сделаю окончательные выводы о пригодности моей задумки.

Остальное не буду комментировать.

PS Допишу - выложу на всеобщее порицание.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38585687
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати вот сейчас мучаюсь с проблемами гарантированного таймаута, так вот, могу сказать, что сети с файерволами себя ведут порой абсолютно не так, как сети без них.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38585688
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЭто п.1, а как обойти NAT я выше написал.
почитал бы про типы NAT сначала(rfc 4787)


UDP пакеты в 6000 байт - это сильно, при передаче они разбиваются на фрагменты, один фрагмент выпал - и пропал весь пакет.да и нет никаких гарантий, что длинный пакет пройдёт по сети(rfc 5405)
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38586694
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TЭто п.1, а как обойти NAT я выше написал.
почитал бы про типы NAT сначала(rfc 4787)
Ниасилю, там много непонятных английских букв :)
Да и дело не в натах, а в ограничении и фильтрации трафика провайдерами, вирусную активность пресекают и слишком любящих покачать все на свете домашних пользователей ловят. Думаю про это rfc не пишут.
Я уже попался :) пытался без сервера своих UDP-клиентов соединить из-за виндовых брандмауэров, написал сканер портов встречный, т.е. указываешь проге IP и он его ему шлет маленький пакетик на все порты, а на том IP такая же прога навстречу. Пролетело - соединились. В локалке заработало, направил на внешние IP натов ... инет отпал через минуту )))

И не критично это. Ну не заработает между двумя клиентами p2p - есть сервер, через него трафик пропущу. Просто реально может оказаться что оба клиента на одном провайдере, в одном городе, а трафик пойдет на сервер и обратно 5-7 тыс.км. Так и ходит сейчас. Не быстро получается. Также при наличии p2p можно было бы пользователям предложить удобный канал обмена их собственной инфой между их точками. Отсутствие узкого места в виде сервера значительно расширяет потенциальные возможности.

ИзопропилUDP пакеты в 6000 байт - это сильно, при передаче они разбиваются на фрагменты, один фрагмент выпал - и пропал весь пакет.да и нет никаких гарантий, что длинный пакет пройдёт по сети(rfc 5405)
Ну это я опытным путем выяснял какие пролазят. Лучше бы по-простому сказал какой максимальный размер взять.
По результатам тестов пришел к размеру 1372 байта. Пока остановился на нем. Это предел для L2TP подключения с MTU 1400.
Поиски по инету ответа не дают. Есть магическое число 1280 от MS в описании настройки DNS
Есть RFC 1191, где упоминается магическое число 576, правда сам RFC 1990 года рождения.
rfc 5405 попробую осилить. Там тоже 576 упоминается для IPv4

Уменьшить макс.размер можно и до 512, только смущает доля служебной инфы 6,5% против 2,5% для 1372. (20 байт IP заголовок + 8 UDP + 10 мой). С другой стороны разбиение на фрагменты похоронит всю экономию и даст доп.тормоза.

Как раз добрался до тестов максимально возможной скорости. Идея такая: слать окнами по десять пакетов и выравнивать интервал по времени, т.е. например засечь время, послать 10 пакетов макс.размера, дождаться окончания 1 мс, следующие 10 пакетов и т.д. И найти такой минимальный временной интервал при котором без потерь будет идти непрерывная передача. Тут заодно можно будет посмотреть как размер пакета влияет на общую полезную скорость и потери.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38586705
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПричем тут очки? Конкретных фактов не приведено, есть просто общий скепсисЖизнеспособность равноправных сетей определяется только одним фактором: наличием у "кормильцев" достаточных ресурсов для обслуживания всех "пиявок".
А какими будут протокол и транспорт ... Да хоть голубинная почта.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38586709
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tпослать 10 пакетов макс.размера, дождаться окончания 1 мс, следующие 10 пакетов и т.д.Может, у меня с арифметикой что не так, но по моим подсчетам это поток порядка 100 Мбит/с.
Такого интернета у большинства и близко нет. А у некоторых до сих пор 32 Кбит/с.

Оффтоп: Кстати, практически единственный современный сайт, который юзабелен при 32 Кбит/с - это sql.ru :)
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38586711
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКак раз добрался до тестов максимально возможной скорости. Идея такая: слать окнами по десять пакетов и выравнивать интервал по времени, т.е. например засечь время, послать 10 пакетов макс.размера, дождаться окончания 1 мс, следующие 10 пакетов и т.д. И найти такой минимальный временной интервал при котором без потерь будет идти непрерывная передача. Тут заодно можно будет посмотреть как размер пакета влияет на общую полезную скорость и потери.Не изобретайте вы TCP на коленке ...
Про стандартную реализацию производители сетевого оборудования наслышаны и приняли немало усилий для "углУбить и расширить", а вот ваши извращения могут и (невинно) пострадать.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38586803
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftDima Tпослать 10 пакетов макс.размера, дождаться окончания 1 мс, следующие 10 пакетов и т.д.Может, у меня с арифметикой что не так, но по моим подсчетам это поток порядка 100 Мбит/с.
Такого интернета у большинства и близко нет. А у некоторых до сих пор 32 Кбит/с.

Оффтоп: Кстати, практически единственный современный сайт, который юзабелен при 32 Кбит/с - это sql.ru :)
1 мс это для примера было, пусть 1 сек. Хотя на 100 Мбит и придется тренироваться в локалке. Хочу разработать методику определения скорости 5-10 пакетами, в идеале с полезной инфой. Хотя максимальная заточка должна быть на те случаи когда все плохо, в первую очередь GSM модемы с неуверенным приемом. Из них надо выжать максимум, а если из доступных 100 Мбит получится 10 - неважно.
Basil A. SidorovНе изобретайте вы TCP на коленке ...
Про стандартную реализацию производители сетевого оборудования наслышаны и приняли немало усилий для "углУбить и расширить", а вот ваши извращения могут и (невинно) пострадать.
Буду изобретать, т.к. :
1. TCP уже есть в виде HTTP поверх него. По сути файлообменник с распределением доступа по логину/паролю.
2. Нужен онлайн обмен маленькими сообщениями, для расширения функционала п.1

п.2 вписывается в особенности UDP идеально, т.к. не заработало по-новому - никто и не заметил, т.к. дальше работает по-старому не догадываясь что может быть лучше.

написал много букав про то чем плох п.1 но стер, т.к. это наше грязное белье не для всеобщего обсуждения
Сухой остаток в том что в идеале я вообще хочу избавится от п.1, мне не нужен сервер, это единственное слабое место в моей системе. Все остальное децентрализовано. Какой бы не был хороший провайдер у которого сервер (а провайдер реально молодец, есть с чем сравнить) он не даст гарантию 100% бесперебойной работы, а 99,99% меня не устраивает, довел до 99,999% использованием второго сервера выполняющего критические ко времени функции первого в случае его отказа, но это полумеры. С UDP я уже спроектировал много-серверную систему с резервированием передаваемых данных, 100% устойчивую к падению одного сервера в час. В случае если p2p заработает, то отказоустойчивость будет 100500%, т.к. каждый клиент станет нужным ему же сервером.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38586812
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TХочу разработать методику определения скорости 5-10 пакетами, в идеале с полезной инфой.Может, не стоит морочиться с замером скорости, а просто ожидать квитирования после каждых 1-10 пакетов?

UDP, кстати, еще хуже тем, что некоторые операторы UDP-пакетам на нестандартных портах дают меньший приоритет, чем для TCP. Если у какого-нибудь такого маршрутизатора по дороге интерфейс "в полке" (т.е. длительно загружен на 100%), то он дропнет все ваши пакеты, а не только 90%.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38586861
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftDima TХочу разработать методику определения скорости 5-10 пакетами, в идеале с полезной инфой.Может, не стоит морочиться с замером скорости, а просто ожидать квитирования после каждых 1-10 пакетов?
Стратегически неправильный подход. Должен быть запас прочности. И чем больше - тем лучше. Можно изначально написать лишь бы работало, а потом ломать голову как улучшить когда будет работать плохо.

Да и просто интересно. Чисто спортивный интерес. Понять как могло бы быть идеально и как далеко от идеала то что получилось. То что будет в итоге не идеально я не сомневаюсь, просто хочу знать насколько.
miksoftUDP, кстати, еще хуже тем, что некоторые операторы UDP-пакетам на нестандартных портах дают меньший приоритет, чем для TCP. Если у какого-нибудь такого маршрутизатора по дороге интерфейс "в полке" (т.е. длительно загружен на 100%), то он дропнет все ваши пакеты, а не только 90%.
Отказаться от UDP никогда не поздно, это просто усложнит решение, я изначально изучал различные системы обмена сообщениями (*MQ) на основе TCP и в итоге пришел к выводу что они своей сложностью только усложняют решение моей задачи, но не дают идеального решения, что-то конечно дают, но не все что надо и очень дорого в плане сопровождения. В итоге пришел к выводу раз изначально все ненадежно, то пусть будет совсем ненадежно, но просто.

Работая на низком ненадежном уровне можно элементарно передать данные со 100% надежностью: Клиент А хочет что-то передать Клиенту Б. Передает всеми доступными способами (напрямую, через доступные сервера, голубями и т.д. чем больше способов доступно тем лучше) пока Клиент Б не скажет я все получил, затем назначается координатор транзакции, который относительно надежный но на всякий случай дублирует себя вторым относительно надежным. Суммарная надежность координаторов 100% если они не умрут одновременно, выживший продублируется третьим и т.д. В итоге Клиент А на 100% уверен что Клиент Б всё получил. Как-то так :)
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38586878
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tmiksoftпропущено...
Может, не стоит морочиться с замером скорости, а просто ожидать квитирования после каждых 1-10 пакетов?
Стратегически неправильный подход. Должен быть запас прочности. И чем больше - тем лучше.Не вижу чем этот подход снижает запас прочности.
Более того, мне видится, что у него запас прочности выше, т.к. он не полагается на столь ненадежную величину как скорость. В сотовых сетях скорость может плавать на порядок в любую сторону несколько раз в течение одной минуты.
Строго говоря, для единичных пакетов понятие скорости вообще слабо применимо, т.к. складывается из сильно и быстро меняющихся факторов.

Кроме того, мой подход вполне можно корректировать. Например, ввести аналог TCP-шного окна. Т.е. дожидаться квитирования не всех пакетов, а всех, кроме N последних.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38586882
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Не думали готовую библиотеку использовать?
В последнее время много BitTorrent Sync обсуждают...
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38587577
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разобрался с потерями в 90%. Все до безобразия просто: виндовс не может отправить два пакета подряд (независимо от размера). Даже с 127.0.0.1 на 127.0.0.1.
такой код почти никогда не отправит второй пакет
Код: plaintext
1.
2.
3.
4.
5.
6.
timeval wait_time;
wait_time.tv_sec = 0;
wait_time.tv_usec = 0;
sendto(sock, ...);
int sel = select(sock + 1, &fd, NULL, NULL, &wait_time);
sendto(sock, ...);


но стоит поставить
Код: plaintext
1.
wait_time.tv_usec = 1;


и все уходит. Только я так подозреваю что тут дело не в 1 микросекунде, а в том что именно в момент такого вызова ОС начинает отправлять, а потом выходит из select() по таймауту.
Нездоровая фигня, но в целом меня это устраивает.

Причем размер пакета тут тоже никак не влияет хоть 10 байт хоть 1024. Тест из 10000 пакетов через 127.0.0.1 уходит 10 сек и на пакете 10 байт и на 1024.

Я все это заметил только когда отладочные printf() убрал. Наверно пока они печатались ОС иногда успевала sendto() обработать и второй срабатывал нормально. И было вообще непонятно в чем причина и как ловить.

PS Сделал p2p клиента с узнаванием друг-друга через сервер. Причесываю исходники. Выложу чуть позже.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38587621
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Код: plaintext
1.
select(sock + 1,


здесь - ошибка. перед копипастом полезно документацию читать
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38587628
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima T
Код: plaintext
1.
select(sock + 1,


здесь - ошибка. перед копипастом полезно документацию читать
Ты сам читал?
http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx int select(
_In_ int nfds,
...
Parameters
nfds [in]
Ignored. The nfds parameter is included only for compatibility with Berkeley sockets.
...
Это как раз правильно, MS пофиг, а линукс только так и понимает.

PS копипаст из моего же творчества.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38587787
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TРазобрался с потерями в 90%. Все до безобразия просто: виндовс не может отправить два пакета подряд (независимо от размера). Даже с 127.0.0.1 на 127.0.0.1.....
Неправильно написал, это убирает потери на стороне отправителя, т.е. с такой паузой виндовс отправит много пакетов. Потери в каналах доставки остаются, но там они боле-мене понятны: шлешь много пакетов с большой частотой - много теряется, шлешь с маленькой частотой - все доходят. Дальше надо решать задачу поиска середины.
Непонятки были из-за отправки: хоть на 127.0.0.1, хоть по гигабитной локалке - все равно потери, причем разные т.к. из-за отладочных printf`ов отправитель подтормажимал и в эти моменты виндовс успевал что-то отправлять.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38588791
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

(просто идея)
А попробуйте вместо задержки вызывать flush для сокета после отправки.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38588793
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА попробуйте вместо задержки вызывать flush для сокета после
отправки.
Лучше будет всё-таки не отправлять сообщение в сокет, которому select вернул состояние
"можно читать". А ещё лучше - не выпендриваться с неблокирующими сокетами вообще.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38588874
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovА ещё лучше - не выпендриваться с неблокирующими сокетами вообще
А, я думал сокет блокирущий.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38589848
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky(просто идея)
А попробуйте вместо задержки вызывать flush для сокета после отправки.
flush() - не нашел такой функции, может речь про файловый fflush() - не компилируется " cannot convert parameter 1 from 'SOCKET' to 'FILE *'"
если насильно fflush((FILE *) sock) - вылетает.

Dimitry SibiryakovЛучше будет всё-таки не отправлять сообщение в сокет, которому select вернул состояние
"можно читать".
Выше пример упрощенный, чтоб не грузить лишними деталями, полные исходники тут (см. udp_dialog.h) , если селект вернул "можно читать" происходит чтение. Проблема была именно когда читать нечего и надо дважды отправить.
Dimitry SibiryakovА ещё лучше - не выпендриваться с неблокирующими сокетами вообще.

Большим спецом по сокетам себя не считаю, могу заблуждаться, но сокет блокирующий. На recvfrom() он останавлиивается, пока что-нибудь не примет. Для того и select() чтоб все не встало в ожидании приема.
Вот код инициализации сокета
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
	WSADATA wsaData;
	if(WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) {
		err = 1;
	}
	#endif
	SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (!err && sock == -1) {
		err = 2;
	}
 	if(!err) {
		if(addr) {
			if(bind(sock, (SOCKADDR *) addr, (socklen_t) sizeof(sockaddr_in)) != 0) {
				err = 3;
			}
		} else {
			sockaddr_in addr_any;
			addr_any.sin_family = AF_INET;
			addr_any.sin_port = 0; //htons(0);
			addr_any.sin_addr.s_addr = 0; //htonl(INADDR_ANY);
			if(bind(sock, (SOCKADDR *) &addr_any, (socklen_t) sizeof(sockaddr_in)) != 0) {
				err = 3;
			}
		}
	}

...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38589870
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tесли селект вернул "можно читать" происходит чтение.
Ты всерьёз считаешь, что "sendto" это чтение? У тебя в select третий параметр NULL - ты не
проверяешь можно ли писать в сокет, но пишешь.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38589872
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov А ещё лучше - не выпендриваться с неблокирующими сокетами вообще.
А все таки, что вы имели ввиду под "неблокирующими сокетами"?
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38589908
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovDima Tесли селект вернул "можно читать" происходит чтение.
Ты всерьёз считаешь, что "sendto" это чтение?
Промолчу
Dimitry Sibiryakov У тебя в select третий параметр NULL - ты не
проверяешь можно ли писать в сокет, но пишешь.

Можно чуть подробнее.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38589912
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Топик напоминает художника, рисующего слона наощупь в темной комнате.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38589922
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинА все таки, что вы имели ввиду под "неблокирующими сокетами"?
Сокеты, к которым применено ioctlsocket(FIONBIO). Они в сочетании с отсутствием проверки
на возможность записи в select() и кода возврата sendto (то есть именно так как писал
афтор в этом топике) приводят как раз к эффекту "пропадания пакетов". В другом топике у
автора есть проверка кода возврата, и нет вызова ioctl, так что можно сделать вывод, что
хотя сокеты у него и блокирующие, винда нагло выкидывает UDP данные если под них нет
свободного буфера.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38589936
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivТопик напоминает художника, рисующего слона наощупь в темной комнате.
Если ты про меня, то вместо сарказма подскажи что почитать, если считаешь что отвечать долго. 10 лет осваивал фокс, столько же умничаю на фоксовом форуме, параллельно кое-что на си писал, только чтобы от winapi получить то что фокс не может, но не могу себе позволить 10 лет потратить на заработку звания гуры в низкоуровневом программировании, не надо оно мне, да и жить вечно не планирую. Поднял вопрос не чтобы чем-то похвастаться.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38589944
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TМожно чуть подробнее.
Dima Tвместо сарказма подскажи что почитать
Описание select() разве не самоочевидное чтиво?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38589946
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovDima TМожно чуть подробнее.
Dima Tвместо сарказма подскажи что почитать
Описание select() разве не самоочевидное чтиво?..

Намеки выше понял, читаю... проще надо быть.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38590353
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

У тебя идеологические проблемы на мой взгляд. UDP про жизни теряет. А ты хочешь не терять. Надо учиться просто "жить" даже при условии силу тебя что-то теряется.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38590455
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivDima T,

У тебя идеологические проблемы на мой взгляд. UDP про жизни теряет. А ты хочешь не терять. Надо учиться просто "жить" даже при условии силу тебя что-то теряется.
Пока у меня проблемы "чайника", я уперся в то что пакет теряется на отправителе, sendto() срабатывает без ошибок, а виндовс молча убивает. Надо просто разобраться как быть уверенным что действительно пакет ушел. В идеале чтобы sendto() дождался отправки прежде чем что-то вернет (я считал что оно так и происходит). Думаю это идеологию не нарушает. Порешал пока добавив таймаут в select(), сам понимаю что коряво.
Пока времени нет, попозже буду изучать select(), ioctlsocket().

Мне бы какую-нибудь статью нормальную чтоб там все сразу вместе было собрано про работу с сокетами. Чтобы тонкости и ньюансы понять. Желательно на русском.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38590467
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока у меня проблемы "чайника", я уперся в то что пакет теряется на отправителе, sendto() срабатывает без ошибок, а виндовс молча убивает.

Так в UDP они по жизни теряются. что тут разбираться ?


Надо просто разобраться как быть уверенным что действительно пакет ушел.

Никак. Ты можешь только слать квитки с другой стороны сети.


В идеале чтобы sendto() дождался отправки прежде чем что-то вернет (я считал что оно так и происходит).


Так делай синхронный сокет. Правда, он тебе не даст гарантию, что он отправил, даст толко что он попытался отправить.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591048
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TМне бы какую-нибудь статью нормальную чтоб там все сразу вместе было собрано про работу с сокетами. Чтобы тонкости и ньюансы понять. Желательно на русском.Я тебе уже давал ссылку на целый учебник. Там ВСЕ расписано. И как сокеты работают, и как p2p делать и несколько алгоритмов сетей разобрано.
Берешь и читаешь.
И на русском - тоже есть учебники. Не уверен что тот который я показал переводили, но и других хватает. Идешь в свой любимый магазин и ищешь там все что имеет в названии "TCP/IP".
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591058
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот исходник, если кто глянуть захочет, красным выделены добавленные проверки
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
int udp_dialog(sockaddr_in* addr, int buf_count)
{
	int err = 0;
	// инициализация сокета
	#if defined WIN32
	WSADATA wsaData;
	if(WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) {
		err = 1;
	}
	#endif
	SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (!err && sock == -1) {
		err = 2;
	}

	if(!err) {
		// блокирующий режим
		u_long iMode = 0; // 0 - Disabled Nonblocking mode
		int iResult = ioctlsocket(sock, FIONBIO, &iMode);
		if (iResult != NO_ERROR) {
		  printf("ioctlsocket failed with error: %ld\n", iResult);
		}
	}

	if(!err) {
 // Установка размера буфера исходящих
		int size = (1024*100) ;
		if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof(size)) == -1 ) {
			printf("setsockopt SO_SNDBUF failed\n");
		}
// установка времени отправки, мс
		int time = 100;
		if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &time, sizeof(time)) == -1 ) {
			printf("setsockopt SO_SNDTIMEO failed\n");
		}
	}

 	if(!err) {
		if(addr) {
			if(bind(sock, (SOCKADDR *) addr, (socklen_t) sizeof(sockaddr_in)) != 0) {
				err = 3;
			}
		} else {
			sockaddr_in addr_any;
			addr_any.sin_family = AF_INET;
			addr_any.sin_port = 0; //htons(0);
			addr_any.sin_addr.s_addr = 0; //htonl(INADDR_ANY);
			if(bind(sock, (SOCKADDR *) &addr_any, (socklen_t) sizeof(sockaddr_in)) != 0) {
				err = 3;
			}
		}
	}
	// выделение памяти под буферы приема
	buffer_t* buffers = NULL;
	if(!err && buf_count > 0) {
		buffers = (buffer_t*) calloc(buf_count, sizeof(buffer_t));
		if(!buffers) {
			err = 4;
		}
	}
	// прием и обработка сообщений
	if(!err) {
		buffer_t* buf_end = buffers + buf_count - 1; // последний буфер
		buffer_t* buf_read = buf_end; // буфер для приема
		buffer_t* buf_parse = buffers; // буфер для обработки
		bool queue_empty = true;
		timeval wait_time;
		wait_time.tv_sec = 0;
		wait_time.tv_usec = 0;
		// Ожидание сообщений
		while(true) {
			// проверка наличия входящего сообщания
			fd_set fd;	
			FD_ZERO(&fd);
			FD_SET(sock, &fd);
			int sel = select(sock + 1, &fd, NULL, NULL, &wait_time);
			wait_time.tv_usec = 0; // если поставить 0 не успевают отправляться
			if(sel == -1) {// SOCKET_ERROR
				err = 5;
				break;
			} else if(sel == 0 || buf_read == buf_parse) { // принимать нечего или некуда
				int size_to_send = 0;
				if(buf_parse->size != 0) {
					// обработка сообщения
					size_to_send = parse_udp_message(buf_parse->msg, buf_parse->size, buf_parse->addr);
					buf_parse->size = 0; // пометка буфера пустым
				} else {
					// отправка по собственной инициативе
					int sleep_msec = 100; // пауза 0.1 сек если отправитель не изменит
					size_to_send = send_udp_message(buf_parse->msg, buf_parse->addr, sleep_msec);
					if(size_to_send == 0 && sleep_msec > 0) { // установка паузы если слать нечего
						wait_time.tv_usec = sleep_msec < 1000 ? sleep_msec * 1000 : 999999;
					}
				}
				if(size_to_send >= UDP_MIN_SIZE) {
					fd_set fd;	
					FD_ZERO(&fd);
					FD_SET(sock, &fd);
					int sel = select(sock + 1, NULL, &fd, NULL, &wait_time);
					if(sel == 0) {
						printf("socket select error\n");
					}
					if(FD_ISSET(sock, &fd) == 0) {
						printf("socket send error\n");
					}

					// отправка UDP пакета
					int s = sendto(sock, buf_parse->msg, size_to_send, 0, (SOCKADDR *) &buf_parse->addr, sizeof(sockaddr_in));
					if(s != size_to_send) {
						printf("sendto() size error\n");
					}
				} else if(size_to_send < 0) {
					break; // выходим из цикла обработки сообщений
				}
				queue_empty = next_buffer(&buf_parse, buffers, buf_end, buf_read); // переходим к следующему буферу
			} else if(FD_ISSET(sock, &fd) == 0) {
				printf("socket read error\n");
			} else {
				// прием UDP пакета
				socklen_t addr_size = sizeof(sockaddr_in);
				int size = recvfrom(sock, buf_read->msg, UDP_MAX_SIZE, 0, (SOCKADDR *) &buf_read->addr, &addr_size);
				if(size >= UDP_MIN_SIZE) {
					// прочитано успешно
					buf_read->size = size;
					if(queue_empty) {
						buf_parse = buf_read;
					}
					next_buffer(&buf_read, buffers, buf_end); // переходим к следующему буферу
				}
			}
		}
	}

	// выход
	if(buffers) {
		free(buffers);
	}
	if(sock != -1) {
		#if defined WIN32
		closesocket(sock);
		#elif defined __linux__
		close(sock);
		#endif
	}
	#if defined WIN32
	WSACleanup();
	#endif
	return err;
}


Пробовал по отдельности и вместе:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
u_long iMode = 0; // 0 - Disabled Nonblocking mode
int iResult = ioctlsocket(sock, FIONBIO, &iMode);
if (iResult != NO_ERROR) {
...
int size = (1024*100) ;
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof(size)) == -1 ) {
...
int time = 100;
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &time, sizeof(time)) == -1 ) {
...
int sel = select(sock + 1, NULL, &fd, NULL, &wait_time); // перед sendto()
if(sel == 0) 
if(FD_ISSET(sock, &fd) == 0)
...
int s = sendto(sock, buf_parse->msg, size_to_send, 0, (SOCKADDR *) &buf_parse->addr, sizeof(sockaddr_in));
if(s != size_to_send)


Не помогло ничего. При этом ни один if() не сработал. Ни одного printf() об ошибке не вывел. Виндовс тупо сообщает что все отлично, но получатель стабильно получает 1-3 пакетов из 100 отправленных непрерывным потоком. Может что-то накосячил в коде проверок, делал по примерам MSDN.

Меняем таймаут select() с 0 на 1 мксек. и все отлично, 100 из 100 доставлено (на 127.0.0.1 и в локалке). Похоже это единственный вариант протолкнуть пакеты наружу. Оставляю этот костыль.

MasterZivТак в UDP они по жизни теряются. что тут разбираться ?
Похоже ты прав. Пусть теряются и не надо ломать голову где.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591063
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlЯ тебе уже давал ссылку на целый учебник. Там ВСЕ расписано. И как сокеты работают, и как p2p делать и несколько алгоритмов сетей разобрано.
Я его даже скачал, только там 700 страниц, в любом случае почитаю.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591148
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все что выше написано - это мой бред и домыслы. Сообщения доходят и рубятся получателем . Виндовс отправителя все честно отправил без пауз в 1 мкс.
Определил так: поставил на получателя wipfw и настроил запись в лог UDP. Вижу в логе 100 входящих пакетов. Получатель видит 1-2. Вывод: мой получатель с буферизацией чтения бесполезен.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591227
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВсе что выше написано - это мой бред и домыслы. Сообщения доходят и рубятся получателем . Виндовс отправителя все честно отправил без пауз в 1 мкс.


Ну, помнишь, что я говорил про слона
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591373
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дубль 2.
Dima TВсе что выше написано - это мой бред и домыслы. Сообщения доходят и рубятся получателем . Виндовс отправителя все честно отправил без пауз в 1 мкс.
Определил так: поставил на получателя wipfw и настроил запись в лог UDP. Вижу в логе 100 входящих пакетов. Получатель видит 1-2. Вывод: мой получатель с буферизацией чтения бесполезен.
Вася УткинDima Tпропущено...

setsockopt(SO_RCVBUF) оно?


Пробовали делать на принимающей стороне ?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 // Установка размера.
  int size_write = (1024*100) ;
  if ( setsockopt ( UDP_s,
                    SOL_SOCKET,
                    SO_RCVBUF,
                    &size_write,
                    sizeof(size_write)
                   ) == -1 )


Проблему решило?
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591446
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинSO_RCVBUF
Проблему решило?
Не совсем. Эффекта никакого не дало в том виде как у меня написан прием.
Делал так (на 200 пакетов)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
	SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (!err && sock == -1) {
		err = 2;
	}
	if(!err) {
		// Установка размера буфера входящих
		int size = (1024*200) ;
		printf("set SO_RCVBUF = %d\n", size);
		if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof(size)) == -1 ) {
			printf("setsockopt SO_RCVBUF failed\n");
		}
	}


Замена цикла приема на такой дает прием всех 100.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
while(true) {
	// прием UDP пакета
	sockaddr_in from;
	char msg[UDP_MAX_SIZE];
	socklen_t addr_size = sizeof(sockaddr_in);
	int size = recvfrom(sock, msg, UDP_MAX_SIZE, 0, (SOCKADDR *) &from, &addr_size);
	if(size >= UDP_MIN_SIZE) {
		//printf("%d: recvfrom()\n", clock());
		// прочитано успешно, обрабатываем
		int size_to_send = parse_udp_message(msg, size, from);
		if(size_to_send >= UDP_MIN_SIZE) {
			// отправка ответа
			if(sendto(sock, msg, size_to_send, 0, (SOCKADDR *) &from, sizeof(sockaddr_in)) <= 0) {
				printf("sendto() error\n");
			}
		}
	}
}


это при условии быстрой отработки parse_udp_message(). В данном случае у меня там только проверка номера пакета. Отправка происходит только после приема 100-го пакета.

Но стоит добавить printf() (закомментирован который) - начинает теряться половина пакетов. Но если добавить установку SO_RCVBUF то начинает принимать все 100.
Т.е. установка SO_RCVBUF что-то дает, но по какому-то хитрому алгоритму.
Скорее всего никакой хитрости нет, а есть изначальная заточка под прием потокового медиа трафика.

MasterZivНу, помнишь, что я говорил про слона
Да уж, слон не удался. Буду нового рисовать :)

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

Странно что select() в исходном варианте дал такой нездоровый эффект. Я ему даже таймаут повышал, чтобы только select() и recvfrom() работали пока поток идет. Надо еще поизучать что там реально происходит. ХЗ только как тестить если printf() все меняет.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591661
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TНо стоит добавить printf() (закомментирован который) - начинает теряться половина пакетов. Но если добавить установку SO_RCVBUF то начинает принимать все 100.
Т.е. установка SO_RCVBUF что-то дает, но по какому-то хитрому алгоритму.
Скорее всего никакой хитрости нет, а есть изначальная заточка под прием потокового медиа трафика.
Какая ещё хитрость? Просто увеличил размер внутреннего кольцевого буфера UDP и теперь туда влезают все 100 пакетов, даже если ты не успел ни один из них вычитать.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591854
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинКакая ещё хитрость? Просто увеличил размер внутреннего кольцевого буфера UDP и теперь туда влезают все 100 пакетов, даже если ты не успел ни один из них вычитать.
Все верно. Опять я фантазирую. Нашел косяк, потери были уже в моем самодельном кэше. Попробую вообще от него избавиться.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591881
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TВася УткинКакая ещё хитрость? Просто увеличил размер внутреннего кольцевого буфера UDP и теперь туда влезают все 100 пакетов, даже если ты не успел ни один из них вычитать.
Все верно. Опять я фантазирую. Нашел косяк, потери были уже в моем самодельном кэше. Попробую вообще от него избавиться.
А вам не критично если все таки иногда 1-2 или 10-20 пакетов будут теряться?
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591941
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинDima Tпропущено...

Все верно. Опять я фантазирую. Нашел косяк, потери были уже в моем самодельном кэше. Попробую вообще от него избавиться.
А вам не критично если все таки иногда 1-2 или 10-20 пакетов будут теряться?
Не критично до 5% от общего количества.

Мой кэш может как-то помочь потери уменьшить? Мне 1 Мб буфера ОС с запасом хватит.
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38591952
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TВася Уткинпропущено...

А вам не критично если все таки иногда 1-2 или 10-20 пакетов будут теряться?
Не критично до 5% от общего количества.

Мой кэш может как-то помочь потери уменьшить? Мне 1 Мб буфера ОС с запасом хватит.
Нет, не поможет. Ставьте 1-4МБ буфер UDP и убирайте свой кэш. Собственно всё :)
...
Рейтинг: 0 / 0
Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
    #38592019
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинНет, не поможет. Ставьте 1-4МБ буфер UDP и убирайте свой кэш. Собственно всё :)
Убрал свой, поставил 2 Мб. Все работает. Потестил через инет: 90-100 доходит при отправке потоком.

Всем спасибо за участие.

Сделаю паузу, займусь чтением умной книжки по сетям. Чтобы мелкие косяки вперемешку с недопонимаем не приводили к рисованию слонов.
...
Рейтинг: 0 / 0
74 сообщений из 74, показаны все 3 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Чтение и запись в UDP сокет большой очереди пакетов. Как оптимизировать?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]