powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / помогите с логикой, туплю
25 сообщений из 25, страница 1 из 1
помогите с логикой, туплю
    #39397737
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дано: Linux Debian 8.5, прога на gcc-4.9, которая опрашивает
периферию по протоколу UDP порт 1234.

Периферия присылает на порт 1234 пакет авторизации, где указан код узла и IP-адрес периферии.
согласно этим данным головной поток устанавливает соединение и считывает данные с периферии.
Когда задач авторизации приходит много, головной поток не успевает их обработать и задачи "теряются".

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

Подскажите уважаемые профессионалы, как организовать обмен.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397745
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UDP пакеты могут теряться, это нормально.

Для начала просто увеличь размер буфера сокета.
Код: plaintext
1.
2.
3.
4.
	int size = UDP_BUF_SIZE;
	if (setsockopt(sock_udp, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof(size)) != 0 ) {
		... ошибка
	}



Если не поможет, то выноси подготовку ответа в отдельный поток. Т.е. один поток принимает UDP пакеты и ставит в очередь на обработку, второй извлекает из очереди, обрабатывает и отправляет ответ.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397749
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Спасибо большое. буфера мне вполне хватает, проблема в том, что один сеанс обмена с периферией, это примерно 30 запрос-ответов, и в это время приходит задача авторизации от другого узла периферии, которая сейчас просто игнорируется до окончания сеанса обмена с текущим узлом.
если я создам отдельный поток на обработку ответов, то тоже проблема, допустим один узел находится на 15 шаге запрос-ответов, второй на втором шаге запрос-ответов, а третий только что прислал задачу авторизации. Как разрулить?
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397761
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Асинхронно обрабатывать. Сделай структуру для хранения текущего состояния обмена в одним авторизующимся, там храни все что касается его, т.е. текущее состояние синхронизации. Назовем ее auth_t
У каждого спрашивающего есть какой-то свой уникальный IP:порт, используй его как идентификатор.

Все структуры собери в map
Код: plaintext
1.
std::map<IP:порт, auth_t> devices;


Чтобы компараторы не писать можешь "IP:порт" преобразовать в int64_t

Дальше алгоритм простой, в цикле:
ждешь UDP пакет, по приходу пакета получаешь указатель на структуру данного отправителя
Код: plaintext
1.
auth_t* p = devices[IP:порт];


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

Так хоть 100500 параллельно обрабатывай.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397770
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Спасибо большое! Смысл поняла.

Осталось придумать как опрос разбить на шаги.
допустим опрашиваю в цикле часовые архивы. приходит ответ <IP:port:номер шага>
и получается, что надо нырнуть в середину цикла опроса часовых архивов, если перед этим занималась чем-то другим.

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

Никогда не разбивала программу на изолированные шаги, чтобы можно было в любой момент выйти на некоторое время
и зайти в программу снова не потеряв предыдущих вычислений.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397781
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mari.PОсталось придумать как опрос разбить на шаги.
допустим опрашиваю в цикле часовые архивы. приходит ответ <IP:port:номер шага>
и получается, что надо нырнуть в середину цикла опроса часовых архивов, если перед этим занималась чем-то другим.
Запоминать состояние в структуре auth_t, т.е. при отправке запроса запоминаем там: отправлен запрос архива, а по приходу ответа смотрим там что запрашивали.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397804
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Да, по-ходу это очередь получается. Когда-то давно (в 1991 году) мы такое в MS-DOS реализовывали. Там
не было возможности создавать потоки и наш шеф написал библиотеку, имитирующую многопоточность.
Те была прога обработки очереди, на вход которой подавались структуры заданий (например один шаг цикла).
А каждая клиентская прога должна была разбить свое выполнение на задания и подсовывать их в очередь.
Таким образом вроде бы все выполнялось параллельно. Вот никогда бы не подумала, что мне это вспомнить придется )))
Спасибо большое!
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397813
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mari.PА перед входом в цикл там куча значений вычисляется (маркер архива, общее число показаний и тп, индекс цикла)
Если это все поместить в структуру, описывающую узел периферии, то это монстр какой-то получится.

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

Можно по другому, оставить твой алгоритм как есть. Если одновременно обменов не много, то можно сделать через отдельные потоки и очереди. Вместо очереди можешь UDP порт на 127.0.0.1 использовать.
Делаешь хранилище очередей
Код: plaintext
1.
std::map<IP:порт девайса, порт обработчика> queue;


При запуске потока обмена он открывает UDP сокет на 127.0.0.1:* и регистрирует его в queue

Поток приема UDP принимает пакет со внешнего порта, находит в queue локальный порт куда переслать и пересылает.

Поток обработки принимает с локального порта, а отправляет во внешний.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397829
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Как сказать немного, узлов 300, задачу авторизации каждый узел генерит 1 раз в 5 мин...
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397850
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mari.PDima T,

Как сказать немного, узлов 300, задачу авторизации каждый узел генерит 1 раз в 5 мин...
Не обязательно 300 потоков постоянно держать. Хотя можно и держать, комп выдержит, но некрасиво это.
Одновременно, как понял, максимум обмен с 2-3 узлами идет, поэтому лучше так: при необходимости обмена с конкретным узлом запускается отдельный поток, обменивается и завершается. Тогда лишних потоков висеть не будет.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397867
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПоток обработки принимает с локального порта, а отправляет во внешний.
Если так будешь делать, то отправку во внешний не забудь обернуть в блокировку мутексом, чтобы разные потоки одновременно не слали. Принимать одним потоком и слать другим можно, а вот слать несколькими - это под вопросом.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39397967
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Так не буду делать, буду "наизнанку выворачивать". Как-то некорректно все-таки
пришедший готовый пакет еще куда-то отправлять....
Хотя да, процедуру обмена придется полностью переписывать.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39398114
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mari.PКак-то некорректно все-таки пришедший готовый пакет еще куда-то отправлять....

Конечно некорректно. Зачем громоздить такие сложности, когда достаточно реализовать
паттерн producer-consumer, а в consumer встроить конечный автомат с состоянием?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39398183
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovMari.PКак-то некорректно все-таки пришедший готовый пакет еще куда-то отправлять....

Конечно некорректно. Зачем громоздить такие сложности, когда достаточно реализовать
паттерн producer-consumer, а в consumer встроить конечный автомат с состоянием?


паттерн producer-consumer - а что это? не подскажете?
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39398221
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шаблон проектирования Producer-Consumer .

ИМХО лишнее это, он для высоконагруженных систем, для 300 обменов раз в 5 минут одного потока хватит.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39398266
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИМХО лишнее это, он для высоконагруженных систем, для 300 обменов раз в 5 минут одного
потока хватит.

Раз у аффтара теряются пакеты, значит не хватает. Помимо всего прочего, такой рефакторинг
повысит модульность и как следствие - сопровождаемость кода.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39398271
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovРаз у аффтара теряются пакеты, значит не хватает.

Не теряются, она их сама не обрабатывает, т.к. алгоритм синхронный 20175832
Mari.Pпроблема в том, что один сеанс обмена с периферией, это примерно 30 запрос-ответов, и в это время приходит задача авторизации от другого узла периферии, которая сейчас просто игнорируется до окончания сеанса обмена с текущим узлом.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39398274
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovDima TИМХО лишнее это, он для высоконагруженных систем, для 300 обменов раз в 5 минут одного
потока хватит.

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


пакеты не теряются, я их сама игнорировала, пока не закончу обмен.
сейчас сделала временные костыли - храню в массиве структур пришедшие во время сеанса обмена задачи авторизации от других узлов
и по окончании обмена обрабатываю их. Один сеанс длится где-то около 5 сек, так что вроде успеваю.
Но вообще говоря переделывать надо.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39398278
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mari.PЕсли это все поместить в структуру, описывающую узел периферии, то это монстр какой-то получится
не обязательно монстр, структура может быть просто развесистой


PS а в качестве примера можно посмотреть исходники nginx
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39404903
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилPS а в качестве примера можно посмотреть исходники nginx

Ничего себе там исходников-то.....
https://trac.nginx.org/nginx/browser?_ga=1.32480254.1376089487.1487152273#nginx/src/core


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

У меня один вопрос - допустим один поток ждет пакет UDP на порту 1234.
Код: plaintext
1.
bytes = recvfrom(sock, buf, sizeof(buf), 0, &rcvr_name, &namelen);



Другой поток может посылать пакеты по UDP в тот же порт 1234?
Это не приведет к тому, что первый поток ничего не дождется?
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39404924
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mari.PУ меня один вопрос - допустим один поток ждет пакет UDP на порту 1234.
Код: plaintext
1.
bytes = recvfrom(sock, buf, sizeof(buf), 0, &rcvr_name, &namelen);



Другой поток может посылать пакеты по UDP в тот же порт 1234?
Это не приведет к тому, что первый поток ничего не дождется?
Что пришлют то и получит.
Слать можно откуда угодно, открывай в другом потоке новый сокет и шли с него на 127.0.0.1:1234.
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39404937
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TMari.PУ меня один вопрос - допустим один поток ждет пакет UDP на порту 1234.
Код: plaintext
1.
bytes = recvfrom(sock, buf, sizeof(buf), 0, &rcvr_name, &namelen);



Другой поток может посылать пакеты по UDP в тот же порт 1234?
Это не приведет к тому, что первый поток ничего не дождется?
Что пришлют то и получит.
Слать можно откуда угодно, открывай в другом потоке новый сокет и шли с него на 127.0.0.1:1234.

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

Вопрос - первый и второй потоки не будут друг другу мешать? Короче можно делать отправку и получение "одновременно"
или надо семафорить?
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39404946
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mari.PВопрос - первый и второй потоки не будут друг другу мешать?

Не будут.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39404960
Mari.P
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Спасибо!
...
Рейтинг: 0 / 0
помогите с логикой, туплю
    #39408811
Фотография Santana
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделай структуру для хранения текущего состояния обмена в одним авторизуючися!
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / помогите с логикой, туплю
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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