Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.12.13;
Скачать: CL | DM;

Вниз

UDP-сервер, принимающий пакеты по всем интерфейсам   Найти похожие ветки 

 
Пробегал2...   (2008-05-12 20:42) [0]

Читаю статью Антона Григорьева - http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1021#10  - и не понимаю как сделать UDP-сервер, который принимает соединения по всем интерфейсам. Написано следующее:

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

Для TCP понятно существуют функции Listen и Accept, которые легко использовать и на каждого клиента приходится по своему сокету, а основной сокет в Listen-режиме принимает все запросы установления подключений по всеи интерфейсам, если создан с привязкой InAddr_Any.

Но как реализовать это для UDP?! Не могу понять, а в статье этот пункт не освещен...

P.S. Как я понял по статье, если создать UDP-сокет с привязкой InAddr_Any, то при первой же отправке SendTo будет привязан к конкретному интерфейсу и с других интерфейсов пакеты получать не будет...


 
User1   (2008-05-12 20:48) [1]


> Пробегал2...   (12.05.08 20:42)  

Читай внимательно !


 
Пробегал2...   (2008-05-12 20:53) [2]

спасибо за совет, очень полезно.


 
User1   (2008-05-12 20:58) [3]


> Пробегал2...   (12.05.08 20:53) [2]

:o)


 
Пробегал2...   (2008-05-12 21:05) [4]

хотя по NETSTAT видна куча UDP-сокетов, висящих на 0.0.0.0 интерфейсе (то бишь этот InAddr_Any):

TCP    127.0.0.1:1025         0.0.0.0:0              LISTENING
TCP    192.168.0.1:139        0.0.0.0:0              LISTENING
UDP    0.0.0.0:445            *:*
UDP    0.0.0.0:500            *:*
UDP    0.0.0.0:1038           *:*
UDP    0.0.0.0:1040           *:*
UDP    0.0.0.0:1054           *:*
UDP    0.0.0.0:1056           *:*
UDP    0.0.0.0:1065           *:*
UDP    0.0.0.0:1066           *:*
UDP    0.0.0.0:1067           *:*
UDP    0.0.0.0:1068           *:*
UDP    0.0.0.0:1069           *:*
UDP    0.0.0.0:1070           *:*
UDP    0.0.0.0:4500           *:*


где ошибка, в статье Антона или где?


 
Пробегал2...   (2008-05-13 14:16) [5]

неужели никто не знает...


 
Сергей М. ©   (2008-05-13 15:00) [6]


> сокеты UDP-серверов, работающих в подобных системах, должны
> явно привязываться к нужному адресу


Не должны и не обязаны, но вправе и могут.

Фактическая привязка к конкретному интерфейсу UDP-гнезда, которое было забиндено к INADDR_ANY,  происходит при первом же вызове любой из ф-ций connect(), recvfrom(), sendto()

Отсюда напрашивается и решение - на серверной стороне вместо ф-ций recvfrom() и sendto() использовать, соотв-но, recv() и send()


 
Пробегал2...   (2008-05-13 21:55) [7]

Сергей М. ©   (13.05.08 15:00) [6]
Отсюда напрашивается и решение - на серверной стороне вместо ф-ций recvfrom() и sendto() использовать, соотв-но, recv() и send()


это как это?!

Использование функций без постфикса From возможно только ПОСЛЕ использования функции Connect, который связывает сокет с УДАЛЕННЫМ портом. Для TCP это инициализирует подключение, для UDP включает режим фильтрации для этого сокета по приему пакетов только от указанного удаленного порта...

Поэтому предложение бредово:

1) использовать recv без предварительного connect невозможно... Скорее всего не сработает, но в любом случае ты не будешь знать ОТ КОГО пришло сообщение

2) использовать send без предварительного connect невозможно. Система не будет знать КУДА посылать пакет. Это или указывается в функции SendTo, или отправитель указывается в функции Connect

3) если использовать функцию connect перед recv / send - это приведет к точно такой же привязке к интерфейсу локальному, а еще плюс и привязку к удаленному порту.

Что это за сервер, который работает только с одним удаленным клиентом?!?!


 
Сергей М. ©   (2008-05-14 11:42) [8]

UDP recv():

If unconnected, the socket must be bound, and there are no source address restrictions on datagrams received.

Как видишь, никакой привязки к интерфейсу при этом не происходит.
А то что адрес отправителя при этом не известен, это уже другой вопрос.


 
Пробегал2...   (2008-05-14 13:16) [9]

Сергей М. ©   (14.05.08 11:42) [8]
Как видишь, никакой привязки к интерфейсу при этом не происходит


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

Но отсутствие ограничений по адресу источника не означает, что нет привязки к локальному интерфейсу.

Собственно, я уверен что ты про RecvFrom найдешь тоже самое. После его использование тоже никаких ограничений на адрес источника не накладывается, оно накладывается только функцией connect.


 
Сергей М. ©   (2008-05-14 13:36) [10]


> Пробегал2...   (14.05.08 13:16) [9]


А ты исследовал на эту тему код хотя бы того же IdUDPServer ?


 
Пробегал2...   (2008-05-14 14:07) [11]

Сергей М. ©   (14.05.08 13:36) [10]

нет не исследовал, там же такая иерархия классов, очень много времени надо убить, которого нету.

В общем, судя по всему, Антон Григорьев ошибся и в его статье ошибка. Он сам не знает как будет себя все вести при двух сетевых картах, информацию черпал скудную из разных статей MSDN. Видимо, что-то не так понял.

Никакой привязки при SendTo / RecvFrom не происходит, кроме привязки ко всем интерфейсам. То, что и нужно собственно...


 
Сергей М. ©   (2008-05-14 14:30) [12]


> Пробегал2...   (14.05.08 14:07) [11]


> там же такая иерархия классов, очень много времени надо
> убить


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


 
Пробегал2...   (2008-05-14 14:43) [13]

Сергей М. ©   (14.05.08 14:30) [12]
Не больше часу времени, уверяю


значит ты уже изучил. Расскажи, тогда, пожалуйста ;)

Я думаю они делают обыкновенную привязку к InAddr_Any и не парятся...

Но вот как это будет работать на двух сетевых картах... Нужно иметь две сетевые карты ;)


 
Anatoly Podgoretsky ©   (2008-05-14 14:59) [14]

> Пробегал2...  (14.05.2008 14:43:13)  [13]

Очень просто будет работать, как и положено по RFC - if:port



Страницы: 1 вся ветка

Текущий архив: 2009.12.13;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.018 c
15-1255496803
И. Павел
2009-10-14 09:06
2009.12.13
Компоненты для смены скинов.


6-1210679150
Андрей
2008-05-13 15:45
2009.12.13
Как получить данные от сервера в ответ на post метод


2-1256034201
Yes
2009-10-20 14:23
2009.12.13
определить есть ли связь с базой оракл?


2-1256592395
Евгений Р.
2009-10-27 00:26
2009.12.13
Декодирование PHP строк


2-1256109863
RWolf
2009-10-21 11:24
2009.12.13
AnsiExtractQuotedStr(PChar(str), ...)