Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| |
[WinSock UDP] Спасибо, заработало. Остался маленький вопрос: как работает опция сокета so_reuseaddr? 17.12.04 13:03 Число просмотров: 3220
Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 17.12.04 13:09 Количество правок: 1
|
SO_REUSEADDR — все процессы, которые привязались к одному порту, будут получать одинаковые копии датаграмм, или там какой-то другой механизм?
|
<programming>
|
[WinSock UDP Multicast] Чего-то не работает... 16.12.04 18:16
Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 16.12.04 18:17 Количество правок: 1
|
Итак, есть в локалке программа, периодически посылающая UDP Multicast пакеты. Хочется их принять и поковырять. Параметры UDP у этой программы такие:
Multicast Group: 227.0.0.2
TTL: 7
Adapter IP binding: 127.0.0.1
UDP port: 8167
Что я написал:
Const
adapterIP = '127.0.0.1';
multiGroup = '227.0.0.2';
listenPort: Word = 8167;
Max_Size = 512;
Var
wData: WSADATA;
aSock: TSOCKET;
listener: sockaddr_in;
aStr: String;
t: Integer;
Begin
ZeroMemory(@wData, SizeOf(wData));
Try
If WSAStartup(MAKEWORD(2, 2), wData) <> NO_ERROR Then
Raise Exception.Create('Error at WSAStartup');
Try
WriteLn(wData.szDescription, ' is ', wData.szSystemStatus, '.');
aSock := Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //Говорим, какой сокет мы хотим
WSACheck(aSock <> INVALID_SOCKET);
Try
listener.sin_family := AF_INET; // говорим, что будем слушать
listener.sin_addr.S_addr := inet_addr(adapterIP);
listener.sin_port := htons(listenPort);
WSACheck(bind(aSock, listener, SizeOf(listener)) <> SOCKET_ERROR); //привязываемся к порту
Repeat
SetLength(aStr, Max_Size);
ZeroMemory(PChar(aStr), Max_Size);
t := recvfrom(aSock, PChar(aStr)^, Max_Size, 0, PSockAddrIn(Nil)^, PInteger(Nil)^);
WSACheck(t <> SOCKET_ERROR);
SetLength(aStr, t);
WriteLn('Received: ', aStr);
Until t = 0;
Finally
CloseSocket(aSock);
End;
Finally
WSACleanup;
End;
---
Дык вот, не работает — ничего не ловит! И не могу понять, где применить параметр 227.0.0.2 -- вроде как в мануалах написано, что broadcast'ы c мультикастами и так должны "валиться" в сокет.
Заранее всем спасибо за ответы.
|
|
[WinSock UDP Multicast] лови кусок MSDN 16.12.04 21:34
Автор: NKritsky <Nickolay A. Kritsky> Статус: Elderman
|
Joining and Leaving a Multicast Group
Before a host can receive IP multicast datagrams, it must become a member of one or more IP multicast groups. The following code example shows how a process requests to join a multicast group by using the setsockopt function.
struct ip_mreq mreq;
// mreq is the ip_mreqstructure
{
struct in_addr imr_multiaddr; //The multicast group to join
struct in_addr imr_interface; //The interface to join on
}
#define RECV_IP_ADDR "225.6.7.8" // An arbitrary multicast address
mreq.imr_multiaddr.s_addr = inet_addr(RECV_IP_ADDR);
mreq.imr_interface.s_addr = INADDR_ANY;
err = setsockopt(
sock,
IPPROTO_IP,
IP_ADD_MEMBERSHIP,
(char*)&mreq,
sizeof(mreq));
A socket must bind to an address before calling setsockopt.
Every multicast group membership is associated with a single interface. It is possible to join the same group on more than one interface. To choose the default multicast interface, use INADDR_ANY as the address for imr_interface. To choose a specific interface capable of multicasting, use one of the host's local addresses.
The following code example shows how to leave a multicast group.
struct ip_mreq mreq;
setsockopt(
sock,
IPPROTO_IP,
IP_DROP_MEMBERSHIP,
(char*)&mreq,
sizeof(mreq));
The memberships associated with a socket are dropped when the socket is closed, or the process holding the socket is terminated. However, more than one socket may claim a membership in a particular group, and the host remains a member of that group until the last membership is dropped.
|
| |
[WinSock UDP] Спасибо, заработало. Остался маленький вопрос: как работает опция сокета so_reuseaddr? 17.12.04 13:03
Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 17.12.04 13:09 Количество правок: 1
|
SO_REUSEADDR — все процессы, которые привязались к одному порту, будут получать одинаковые копии датаграмм, или там какой-то другой механизм?
|
| | |
[WinSock UDP] MSDN кстати рулит неподецки 17.12.04 13:21
Автор: NKritsky <Nickolay A. Kritsky> Статус: Elderman
|
> SO_REUSEADDR — все процессы, которые привязались к одному > порту, будут получать одинаковые копии датаграмм, или там > какой-то другой механизм?
MSDN :// HOWTO: Receive/Send Multicasts Under WinNT/Win95 Using WinSock
<skip>
More than one process may bind to the same SOCK_DGRAM UDP port if the bind() call is preceded by the following code:
int one = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one))
In this case, every incoming multicast or broadcast UDP datagram destined for the shared port is delivered to all sockets bound to the port.
<skip>
Иными словами, все привязавшиеся будут получать одинаковые копии пакетов.
|
| | | |
[WinSock] Рулит, спасибо огромное... Ну и наконец, последний вопрос... :) 17.12.04 18:17
Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 17.12.04 18:43 Количество правок: 1
|
1) Опции SO_BROADCAST и/или IP_ADD_MEMBERSHIP, насколько я понял, отбивают охоту у сокета принимать обычные ("прямые") UDP-пакеты. А надо... Есть ли выход?
2) Если указать SO_BROADCAST для сокета, который потом станет IP_ADD_MEMBERSHIP, это как-то повлияет на его работу? Сейчас разницы незаметно, но в примерах это почему-то делают. Вот и хочется узнать, зачем. :)
3) Почему сокет с опцией SO_BROADCAST принимает по две копии broadcast-пакетов?
Заранее большое спасибо.
|
| | | | |
Думаю единственный выход, если это действительно так -... 18.12.04 17:52
Автор: NKritsky <Nickolay A. Kritsky> Статус: Elderman
|
> 1) Опции SO_BROADCAST и/или IP_ADD_MEMBERSHIP, насколько я > понял, отбивают охоту у сокета принимать обычные ("прямые") > UDP-пакеты. А надо... Есть ли выход?
Думаю единственный выход, если это действительно так - байндить другой сокет к тому же порту, но без мультикаста. И принимать обычные датаграммы на него.
> 2) Если указать SO_BROADCAST для сокета, который потом > станет IP_ADD_MEMBERSHIP, это как-то повлияет на его > работу? Сейчас разницы незаметно, но в примерах это > почему-то делают. Вот и хочется узнать, зачем. :)
Не знаю
> 3) Почему сокет с опцией SO_BROADCAST принимает по две > копии broadcast-пакетов?
Не знаю
PS: В MSDN всё время ссылаются по поводу мультикаста на PSDK. Но я бы на твоём месте ещё и книжку какую-нибудь скачал конкретно "про это". Посмотри например на сайте MS что они рекомендуют читать про сетевой стек вообще и мультикаст в частности и скачай pdf/chm откуда-нибудь. Я пока посмотрю - может у меня в сетке что-нибудь завалялось.
|
| | | | | |
Ok. В общем, тулзу ваяю сисадминскую, в дебри PCDK лазить не буду, работает — и то хорошо. А три моих последних вопроса были для удаления тумана, поскольку никогда не программил WinSock. Огромное спасибо за соучастие! ;-) 18.12.04 19:43
Автор: HandleX <Александр М.> Статус: The Elderman
|
|
|
|