Функция accept socket
От: ahaos  
Дата: 01.04.21 02:16
Оценка:
Моя программа рассылает по сети сообщения. Удаленные компьютеры что-то делают и присылают результаты.
Нужно эти результаты принять.

На данный момент я хотел бы для каждого удаленного компьютера на принимающем хосте создать свой поток ожидания с функцией accept. Так и делаю.

Но функция accept срабатывает на все подряд и потокам нужно как-то отфильтровать под себя поступающие пакеты данных, т.е. конкретный поток ожидания должен принять данные только от конкретного удаленного компьютера.
Как это лучше организовать? Или вообще лучше сменить схемы ожидания и приема данных?
Re: Функция accept socket
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.04.21 06:00
Оценка:
Здравствуйте, ahaos, Вы писали:

A>Моя программа рассылает по сети сообщения. Удаленные компьютеры что-то делают и присылают результаты.

A>Нужно эти результаты принять.

A>На данный момент я хотел бы для каждого удаленного компьютера на принимающем хосте создать свой поток ожидания с функцией accept. Так и делаю.


Эээ кто на ком стоял, простите? О каком сетевом API речь?

В BSD sockets (которое скопировано в основах в винде) если UDP, там нет accept(), а если TCP или SCTP, то там... ну, конечно, можно сделать для каждого ремота свой слушающий порт, но зачем?

A>Но функция accept срабатывает на все подряд и потокам нужно как-то отфильтровать под себя поступающие пакеты данных, т.е. конкретный поток ожидания должен принять данные только от конкретного удаленного компьютера.


"Пакеты"? То есть UDP?
(вообще-то датаграммы, но "пакеты" тоже понятно)
Тогда где accept()? Или речь просто про recv()?

A>Как это лучше организовать? Или вообще лучше сменить схемы ожидания и приема данных?


Для начала в них разобраться, а то рассказ на уровне "нажимаю клаксон и машина съезжает на второстепенную".
The God is real, unless declared integer.
Re[2]: Функция accept socket
От: ahaos  
Дата: 01.04.21 06:06
Оценка:
Здравствуйте, netch80, Вы писали:


N>Для начала в них разобраться, а то рассказ на уровне "нажимаю клаксон и машина съезжает на второстепенную".


Речь идет о Win32 Socket2. Используются блокированные сокеты, а также функции send, receive, bind, listen.
Отредактировано 01.04.2021 6:11 ahaos . Предыдущая версия .
Re[3]: Функция accept socket
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.04.21 06:50
Оценка:
Здравствуйте, ahaos, Вы писали:

N>>Для начала в них разобраться, а то рассказ на уровне "нажимаю клаксон и машина съезжает на второстепенную".

A>Речь идет о Win32 Socket2. Используются блокированные сокеты, а также функции send, receive, bind, listen.

Правильно, это и есть BSD sockets (в отличие, например, от XTI sockets, где другие манеры, или ещё нескольких реализаций).
listen() — значит TCP, так? И создаёте по порту на каждый удалённый хост?
Или об установленном соединении? Какая сторона слушает, а какая коннектится к ней?
The God is real, unless declared integer.
Re[4]: Функция accept socket
От: ahaos  
Дата: 01.04.21 07:10
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, ahaos, Вы писали:


N>>>Для начала в них разобраться, а то рассказ на уровне "нажимаю клаксон и машина съезжает на второстепенную".

A>>Речь идет о Win32 Socket2. Используются блокированные сокеты, а также функции send, receive, bind, listen.

N>Правильно, это и есть BSD sockets (в отличие, например, от XTI sockets, где другие манеры, или ещё нескольких реализаций).

N>listen() — значит TCP, так? И создаёте по порту на каждый удалённый хост?
N>Или об установленном соединении? Какая сторона слушает, а какая коннектится к ней?

Нет. Я рассылаю задания удаленным машинам по сети. Далее запускаю сервер, который ждет от них результатов. Сервер слушает только один порт 888.
Поскольку я знаю скольким машинам я послал задание и их адреса, то я создаю на каждую машину свой поток ожидания в котором вызывается accept.
В идеале бы хотелось, что бы accept в своем потоке реагировала на конкретный IP-адрес, а остальные фильтровала, но она срабатывает на все что попало, что приходит на этот сервер. Я конечно проверяю с какого адреса пришло сообщение и если оно пришло с ненужного адреса, я опять в этом потоке возвращаюсь к функции accep и жду нового соединения. Но явно моя конструкция какая-то корявая и весь процесс рано или поздно на чем-то затыкается.
Может все таки нужно запустить один поток ожидания, а там уже разбираться с какой адрес установил соединение и предпринимать соответствующие действия?
Re[5]: Функция accept socket
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.04.21 07:38
Оценка:
Здравствуйте, ahaos, Вы писали:

A>Нет. Я рассылаю задания удаленным машинам по сети. Далее запускаю сервер, который ждет от них результатов. Сервер слушает только один порт 888.

A>Поскольку я знаю скольким машинам я послал задание и их адреса, то я создаю на каждую машину свой поток ожидания в котором вызывается accept.

Таак. Если несколько тредов впараллель запускают accept() на одном слушающем сокете, то они внутри ядра, скорее всего, ставятся в очередь.
Когда придёт входящее соединение, его получит первый из вставших в очередь, следующее — второй, и так далее.
Хотя, может быть, это работает и в обратном порядке (слушание на IOCP, например, активирует последнего из вставших).
В любом случае тут чёткого маппинга, который хотите, не будет.

A>В идеале бы хотелось, что бы accept в своем потоке реагировала на конкретный IP-адрес, а остальные фильтровала, но она срабатывает на все что попало, что приходит на этот сервер. Я конечно проверяю с какого адреса пришло сообщение и если оно пришло с ненужного адреса, я опять в этом потоке возвращаюсь к функции accep и жду нового соединения.


Тогда просто теряете ответ, заставляя удалённую машину повторить его посылку (или потерять).

A> Но явно моя конструкция какая-то корявая и весь процесс рано или поздно на чем-то затыкается.

A>Может все таки нужно запустить один поток ожидания, а там уже разбираться с какой адрес установил соединение и предпринимать соответствующие действия?

Да, можно и так — и это проще всего. Один тред слушает в accept(), на сокет определяет, от кого пришло, и порождает тред для отработки.
Контекст можно передать ему объектом в соответствии с адресом другого конца.

Альтернативно — таки на каждую удалённую машину порождать свой слушающий сокет. Но это хуже масштабируемо.
The God is real, unless declared integer.
Re: Функция accept socket
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 01.04.21 10:28
Оценка: +2
Здравствуйте, ahaos, Вы писали:

A>Как это лучше организовать? Или вообще лучше сменить схемы ожидания и приема данных?

Я тебе советую не заниматься ковырянием сокетов, а взять высокоуровневую либу, например, gRPC, потратить один раз время на то, чтобы разобраться с ней, собрать и подключить к проекту после чего сфокусироваться на бизнес логике приложения, а не на технических деталях реализации транспорта своих данных.
Sic luceat lux!
Отредактировано 01.04.2021 12:04 Kernan . Предыдущая версия . Еще …
Отредактировано 01.04.2021 10:29 Kernan . Предыдущая версия .
Re: Функция accept socket
От: Sm0ke Россия ksi
Дата: 01.04.21 10:43
Оценка:
Здравствуйте, ahaos, Вы писали:

A>Моя программа рассылает по сети сообщения. Удаленные компьютеры что-то делают и присылают результаты.

A>Нужно эти результаты принять.

A>На данный момент я хотел бы для каждого удаленного компьютера на принимающем хосте создать свой поток ожидания с функцией accept. Так и делаю.


A>Но функция accept срабатывает на все подряд и потокам нужно как-то отфильтровать под себя поступающие пакеты данных, т.е. конкретный поток ожидания должен принять данные только от конкретного удаленного компьютера.

A>Как это лучше организовать? Или вообще лучше сменить схемы ожидания и приема данных?

Может вместе с заданием удалённым компам выдавать уникальные ключи (с сохранением этих ключей в мапу). Далее сделать один поток, ожидающий результаты, который проверяет ключ задания. Если ключ найден в мапе, то запускать поток обработки и ждать остальных результатов дальше. Иначе пропуск. Так-же можно учесть ситуацию, когда пришли все ответы.
Re[5]: Функция accept socket
От: удусекшл  
Дата: 01.04.21 12:34
Оценка:
Здравствуйте, ahaos, Вы писали:

A>явно моя конструкция какая-то корявая и весь процесс рано или поздно на чем-то затыкается.


Эт точно


A>Может все таки нужно запустить один поток ожидания, а там уже разбираться с какой адрес установил соединение и предпринимать соответствующие действия?


Да
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.