|
2 / 2 / 0
Регистрация: 06.04.2013
Сообщений: 22
|
|
UDP клиент на сокетах - порты, с которых принимает recvfrom11.07.2013, 16:07. Показов 9571. Ответов 11
Метки нет (Все метки)
Здравствуйте!
Есть вопрос по UDP, постараюсь подробно сформулировать. Ситуация 1: На хосте А на порту 666 есть UDP эхо-сервер (возвращающий, что получил, обратно). На хосте Б на порту 667 такой же. На хосте В клиент отправляет ряд датаграмм с помощью sendto по назначениям: АББАББАББ (порты 666 для А и 667 для Б) и затем в бесконечном цикле вызывается recvfrom. Приходят три ответа А и шесть - Б, в перепутанном порядке. В клиенте на хосте В создается сокет, никакие bind не вызываются, сразу sendto. Ситуация 2: На хосте А запущен эхо-сервер, который принимает датаграммы на порт 666 и отправляет обратно, но на порт 888. Б и В без изменений. Приходят шесть ответов Б. Ситуация 3: На А запущен сервер, отвечающий через 5 секунд, на Б - сразу. Клиент посылает: АБ. Сначала приходит Б, потом А. Вопрос на миллион - как определить, с каких портов можно получить датаграмму функцией recvfrom? По второй ситуации можно сделать вывод, что если сначала вызвать sendto на порт X (и, согласно официальным докам, это неявно вызовет bind и привяжет сокет к локальному адресу), то recvfrom затем может получить только с порта X. Но в первой ситуации сначала производится отправка по-очередно на два разных порта, а затем всем скопом выгребаются принятые датаграммы, причем ни одна не теряется и в буфере они находятся вперемешку, полученные на разные порты (ситуация 3 показывает, что не может быть такого, что ответ получен в буфер еще при передаче, до цикла с recvfrom). В то же время bind привязывает сокет только к одному порту, следуя логике выше, в ситуации 3 последним вызывался sendto на Б и ответ с А получен быть не мог. Но, вообще говоря, bind служит для привязывания сетевого интерфейса (ip адреса, если несколько сетевух), но порт, вроде как, тоже надо указывать (по крайней мере во всех виденных примерах это так). sendto что, каким-то образом инициирует порты для приема? Если так, то каким и как это все работает?
0
|
|
| 11.07.2013, 16:07 | |
|
Ответы с готовыми решениями:
11
Сервер принимает пакеты если клиент указывает неверный порт получателя UDP. Recvfrom() не принимает пакеты UDP Connect не снимает блокировку recvfrom |
|
Модератор
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,457
|
||
| 11.07.2013, 16:40 | ||
|
Добавлено через 1 минуту ..т.е. во втором случае у вас куда-то деваются пакеты от А?
0
|
||
|
2 / 2 / 0
Регистрация: 06.04.2013
Сообщений: 22
|
||
| 11.07.2013, 17:42 [ТС] | ||
|
В случае TCP, клиент, насколько я понял, не может начать получать данные первым, равно как и сервер (слушающий сокет) не может инициировать передачу первым. В случае UDP нет слушающих сокетов и соединения не устанавливаются; вообще не понятно, как можно называть что-то клиентом, а что-то сервером. Во всех примерах, что я видел разница только в том, что в серверах делают bind определенного порта, после чего оттуда можно получать датаграммы. Но в силе вопрос про связку sendto/recvfrom - внезапно выяснилось, что можно получать датаграммы сразу с нескольких портов. Непонятен механизм их "окрытия".
0
|
||
|
Модератор
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,457
|
||
| 12.07.2013, 09:12 | ||
|
0
|
||
|
2 / 2 / 0
Регистрация: 06.04.2013
Сообщений: 22
|
||
| 12.07.2013, 12:47 [ТС] | ||
|
Я разобрался. Разгадка такова: Sendto неявно вызывает bind, привязывая сокет к INADDR_ANY и случайно выбранному свободному порту порядка 50000 (это можно сделать вручную, чтобы порт для приема был известен). Эхо-сервер, описанный в 1 посте, получив на свой 666 порт, отправляет обратно, но не 666 порт клиента, а на этот 50000, вот это я и проглядел. Ответ падает в его буфер (который у каждого порта свой - нельзя слушать больше 1 порта одним сокетом) и забирается recvfrom оттуда (поэтому нельзя вызывать recvfrom до sendto или bind). В ситуации 1 sendto вызывался для двух разных портов - это не важно, потому что локальный порт, с которого все уходило один, фиксированный при первом вызове sendto - 50000, его получали оба эхо-сервера и оба слали обратно на него, поэтому все и доходило. Если коротко: отправка на 666 порт сервера не осуществляется с локального 666 порта клиента.
1
|
||
|
Модератор
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,457
|
|||||||
| 12.07.2013, 13:21 | |||||||
0
|
|||||||
|
2 / 2 / 0
Регистрация: 06.04.2013
Сообщений: 22
|
|||||||
| 12.07.2013, 13:29 [ТС] | |||||||
|
Вызовите в конце getsockname, который возвращает, к чему привязан сокет:
0
|
|||||||
|
Модератор
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,457
|
|
| 12.07.2013, 14:30 | |
|
0
|
|
|
2 / 2 / 0
Регистрация: 06.04.2013
Сообщений: 22
|
||
| 12.07.2013, 14:47 [ТС] | ||
|
0
|
||
|
Модератор
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,457
|
||
| 12.07.2013, 15:10 | ||
|
0
|
||
|
2 / 2 / 0
Регистрация: 06.04.2013
Сообщений: 22
|
||
| 12.07.2013, 15:26 [ТС] | ||
|
Допустим, браузер шлет запрос на удаленный http сервер на порт 80 со своего порта 54321. Сервер видит, что пришло с такого-то ip с порта 54321, и отправляет страницу туда-же на порт 54321. Порт 54321 слушается браузером, пока не будет убит соответствующий открытый сокет. Клиенту открывать свой порт 80 не надо.
0
|
||
|
Модератор
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,457
|
||
| 12.07.2013, 16:08 | ||
|
1
|
||
| 12.07.2013, 16:08 | |
|
Помогаю со студенческими работами здесь
12
Вызовы sento и recvfrom в получении udp пакетов Таймер ожидания для recvfrom (сокеты, UDP) Асинхронный сервер на UDP-сокетах Клиент и сервера на сокетах Клиент-сервер на сокетах Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога
Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
|
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование
. \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json>
Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом.
# Check if. . .
|
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так:
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347
Основана на STM32F303RBT6.
На борту пять. . .
|
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
|
|
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу,
и светлой Луне.
В мире
покоя нет
и люди
не могут жить в тишине.
А жить им немного лет.
|
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила»
«Время-Деньги»
«Деньги -Пуля»
|
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога
Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
|