Легенда:
   новое сообщение
    закрытая нитка
    новое сообщение
    в закрытой нитке
    старое сообщение
         
		 | 
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
 - Новичкам также крайне полезно ознакомиться с данным документом.
   
[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
 | 
 
| 
 | 
 
 
  
 
 | 
 |