Конференция "Сети" » IGMP компоненты [D7, WinXP]
 
  • Zoom © (09.04.10 17:01) [0]
    Существуют ли компоненты для реализации IGMP протокола ?
    и вообще это уже мировой стандарт, или нет, в том смысле все ли  провайдеры поддерживаю мултикаст ? стоит ли разбираться сейчас с этим вопросом если провайдеры окажутся неспособными, или не заинтересованы в этом ? заранее спасибо за любые комментарии!
  • Сергей М. © (09.04.10 21:14) [1]

    > Существуют ли компоненты для реализации IGMP протокола ?


    Может и существуют.
    А что, без них совсем никак ? Типа свет клином сошелся ?


    > все ли  провайдеры поддерживаю мултикаст ?


    Кто хочет  - тот и поддерживает..
    Дело-то добровольное)
  • DVM © (09.04.10 23:17) [2]

    > в том смысле все ли  провайдеры поддерживаю мултикаст ?

    не все, точнее все не поддерживают.
  • Zoom © (10.04.10 17:00) [3]
    Сергей М. , свет клином не сошелся , просто все немного сложнее чем кажется на первый взгляд, нашел пример по постройке IP пакета ...
    http://superadm.net/index.php?name=pages&op=view&id=58
    там хоть и идет речь о  IGMP но не слова о "Membership Query Message".
    http://tools.ietf.org/html/rfc3376#section-4.1

    первый этап - инициализация сокета.
    с какими параметрами инициализировать сокет для отправки Запроса принадлежности (Membership Query Message) ?

    sh := Socket(AF_INET, SOCK_RAW, IPPROTO_UDP);

    // Сергей М. и DVM у вас мнения разошлись на счет провайдеров :)
  • Zoom © (10.04.10 18:08) [4]
    Если кому интересна эта тема, нашел:
    http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzab6/rzab6xmulticast.htm
    есть пример... осталось переложить на Delphi... ох уж эти структуры... сразу, и не переложишь....
  • Zoom © (10.04.10 19:53) [5]
    переложил этот пример http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/rzab6/rzab6x1multicast.htm на нормальный язык, ошибок нет, но и пакеты тоже не уходят... ни лампочки в сети, ни iptools sniffer, никак не реагируют...  


    unit Unit1;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls;

    type
     TForm1 = class(TForm)
       Button1: TButton;
       Memo1: TMemo;
       procedure Button1Click(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
     end;

    type
    ///////////////
    // Некоторые объявления типов для Winsock 2
     u_char = Char;
     u_short = Word;
     u_int = Integer;
     u_long = Longint;

     SunB = packed record
       s_b1, s_b2, s_b3, s_b4: u_char;
     end;
     SunW = packed record
       s_w1, s_w2: u_short;
     end;
     in_addr = record
       case integer of
         0: (S_un_b: SunB);
         1: (S_un_w: SunW);
         2: (S_addr: u_long);
     end;
     TInAddr = in_addr;

     Sockaddr_in = record
       case Integer of
         0: (sin_family: u_short;
           sin_port: u_short;
           sin_addr: TInAddr;
           sin_zero: array[0..7] of Char);
         1: (sa_family: u_short;
           sa_data: array[0..13] of Char)
     end;
     TSockAddr = Sockaddr_in;
     TSocket = u_int;

    const
     WSADESCRIPTION_LEN = 256;
     WSASYS_STATUS_LEN = 128;

    type
     PWSAData = ^TWSAData;
     WSAData = record // !!! also WSDATA
       wVersion: Word;
       wHighVersion: Word;
       szDescription: array[0..WSADESCRIPTION_LEN] of Char;
       szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char;
       iMaxSockets: Word;
       iMaxUdpDg: Word;
       lpVendorInfo: PChar;
     end;
     TWSAData = WSAData;

    // Определяем необходимые функции winsock 2
    function closesocket(s: TSocket): Integer; stdcall;
    function socket(af, Struct, protocol: Integer): TSocket; stdcall;
    function sendto(s: TSocket; var Buf; len, flags: Integer; var addrto: TSockAddr;
     tolen: Integer): Integer; stdcall; {}
    function setsockopt(s: TSocket; level, optname: Integer; optval: PChar;
     optlen: Integer): Integer; stdcall;
    function inet_addr(cp: PChar): u_long; stdcall; {PInAddr;} { TInAddr }
    function htons(hostshort: u_short): u_short; stdcall;
    function WSAGetLastError: Integer; stdcall;
    function WSAStartup(wVersionRequired: word; var WSData: TWSAData): Integer; stdcall;
    function WSACleanup: Integer; stdcall;

    const
     AF_INET = 2; // internetwork: UDP, TCP, etc.

     IP_HDRINCL = 2; // включаем заголовок IP пакета

     SOCK_RAW = 3; // интерфейс raw-протокола

     IPPROTO_IP = 0; // dummy for IP
     IPPROTO_TCP = 6; // tcp
     IPPROTO_UDP = 17; // user datagram protocol
     IPPROTO_RAW = 255; // raw IP пакет

     INVALID_SOCKET = TSocket(not (0));
     SOCKET_ERROR = -1;

     SOCK_DGRAM = 2; // интерфейс udp-протокола
     IP_MULTICAST_LOOP = 4; //???
     IP_MULTICAST_IF = 2; //???
    //http://www.blitzbasic.com/codearcs/codearcs.php?code=1270
    ////////////////

    var
     Form1: TForm1;

    implementation

    // Импортируем функции Winsock 2
    const WinSocket = 'WS2_32.DLL';

    function closesocket; external winsocket name 'closesocket';
    function socket; external winsocket name 'socket';
    function sendto; external winsocket name 'sendto';
    function setsockopt; external winsocket name 'setsockopt';
    function inet_addr; external winsocket name 'inet_addr';
    function htons; external winsocket name 'htons';
    function WSAGetLastError; external winsocket name 'WSAGetLastError';
    function WSAStartup; external winsocket name 'WSAStartup';
    function WSACleanup; external winsocket name 'WSACleanup';

    {$R *.dfm}

    procedure TForm1.Button1Click(Sender: TObject);
    var
     wsdata: TWSAdata;
     ret: Integer;
     sd: TSocket;
     loopch: byte;
     groupSock: TSockAddr;
     localInterface: TInAddr;
     datalen: integer;
     databuf: array[0..1024] of byte;

    begin
    // Startup Winsock 2
     ret := WSAStartup($0002, wsdata);
     if ret <> 0 then begin
       memo1.lines.add('WSA Startup failed.');
       exit;
     end;
     with memo1.lines do begin
       add('WSA Startup:');
       add('Desc.: ' + wsData.szDescription);
       add('Status: ' + wsData.szSystemStatus);
     end;

     try

    // Создаём сокет
       //sd := Socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
       sd := socket(AF_INET, SOCK_DGRAM, 0);
       if (sd = INVALID_SOCKET) then begin
         memo1.lines.add('Socket() failed: ' + IntToStr(WSAGetLastError));
         exit;
       end;
       Memo1.lines.add('Socket Handle = ' + IntToStr(sd));

     (*
      * Initialize the group sockaddr structure with a
      * group address of 225.1.1.1 and port 5555.
      *)

    // memset((char *) &groupSock, 0, sizeof(groupSock));  ???
       groupSock.sin_family := AF_INET;
       groupSock.sin_addr.s_addr := inet_addr('225.1.1.1');
       groupSock.sin_port := htons(5555);

     (*
      * Disable loopback so you do not receive your own datagrams.
      *)


       loopch := 0;
       ret := setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, @loopch, sizeof(loopch));

       if ret = SOCKET_ERROR then begin
         Memo1.lines.add('setsockopt(IP_MULTICAST_LOOP) failed: ' + IntToStr(WSAGetLastError));
         exit;
       end;

      (*
       * set local interface for outbound multicast datagrams.
       * The IP address specified must be associated with a local,
       * multicast - capable interface.
       *)

       localInterface.s_addr := inet_addr('192.168.1.5');
       ret := setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, @localInterface, sizeof(localInterface));

       if ret = SOCKET_ERROR then begin
         Memo1.lines.add('setsockopt(IP_MULTICAST_IF) failed: ' + IntToStr(WSAGetLastError));
         exit;
       end;

     (*
      * Send a message to the multicast group specified by the
      * groupSock sockaddr structure.
      *)

       datalen := 10;
       ret := sendto(sd, databuf, datalen, 0, groupSock, sizeof(groupSock));
       if ret = SOCKET_ERROR then begin
         Memo1.lines.add('sending datagram message: ' + IntToStr(WSAGetLastError));
         exit;
       end;

    // Закрываем сокет
       CloseSocket(sd);
     finally
    // Закрываем Winsock 2
       WSACleanup;
     end;

    end;

    end.

  • Сергей М. © (10.04.10 21:37) [6]

    > DVM ©   (09.04.10 23:17) [2]
    > все не поддерживают.


    Ну это ты загнул)
    За других не скажу, а мой домашний провайдер поддерживает.
    IPTV посматриваю изредка)
  • Zoom © (10.04.10 23:51) [7]
    заменил 'WS2_32.DLL' на 'wsock32.dll' вроде пакеты пошли...
    wsData.szDescription в обоих случаях пишет WinSock 2.0
    в родном winsock.pas используется wsock32.dll ...
    в чем же тогда разница , и что нужно использовать ?
  • Zoom © (11.04.10 01:34) [8]
    перевел на delphi приемную часть , http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/rzab6/rzab6x2multicast.htm

    вроде работает запустил три приложения  все пакеты доставляются правда пока в рамках локальной сети ...

    есть еще вопрос
    у них такая структура на си

    struct ip_mreq
    {
           struct in_addr imr_multiaddr;   /* IP multicast address of group */
           struct in_addr imr_interface;   /* local IP address of interface */
    };

    правильно ли я ее представил ?

     ip_mreq = record
       imr_multiaddr: TInAddr; //* IP multicast address of group */
       imr_interface: TInAddr; //* local IP address of interface */
     end;
     Tip_mreq = ip_mreq;



    такой структуры почему-то нету в winsock.pas...
  • Zoom © (11.04.10 02:41) [9]
    финальное художество http://ontext.info/38740 абстрактно но работает... может кому пригодится...  правда запускать нужно два экземпляра , так как на приеме наглухо замораживается, размораживается по пришествию данных...
  • DVM © (11.04.10 10:54) [10]

    > Сергей М. ©   (10.04.10 21:37) [6]


    > За других не скажу, а мой домашний провайдер поддерживает.
    >
    > IPTV посматриваю изредка)

    Мой тоже и тоже именно для IPTV, фактически поддерживают только те, которым это нужно и обычно эта поддержка имеется только на конечном участке провайдер - пользователи. Оно ж требует вполне конкретной настройки конкретных свитчей под конкретные вещи. Если провайдер ничего такого не предоставляет, то и настроено у него ничего не будет.

    Т.е от Интернет поддержи ожидать не приходится.
  • Zoom © (11.04.10 19:43) [11]
    а вот сделал в качестве юнита http://ontext.info/38746

    пакеты ходят каким то "чудесным" образом, на прием неподвластны даже снифферу :)

    (IGMP)192.168.1.5: ->224.0.0.22:  ,54 Bytes
    (IGMP)192.168.1.5: ->224.0.0.22:  ,54 Bytes
    (UDP)192.168.1.5:1712->225.1.1.1:5555 ,52 Bytes

    как уходят видно, а вот как приходят ... неизвестно... но приходят :)

    с провайдером действительно вроде хана...

    и как настроить роутер на входящее соединение если портов даже нету :)


    procedure TForm1.Button4Click(Sender: TObject);
    begin
     igmp_init_server('192.168.1.5');
     send_databuf[0] := 11; send_databuf[5] := 33; send_databuf[7] := 55; // test data
     igmp_send_data('225.1.1.1', 5555, 10);
    end;

    procedure TForm1.Button5Click(Sender: TObject);

    var
     datalen, i: integer;

    begin
     igmp_init_client('192.168.1.5', '225.1.1.1', 5555);
     igmp_recv_data(datalen);
     Memo1.lines.add('Bytes received: ' + inttostr(datalen));
     if datalen > 0 then for i := 0 to datalen - 1 do Memo1.lines.add(inttostr(i) + ' - ' + inttostr(recv_databuf[i]));
    end;

 
Конференция "Сети" » IGMP компоненты [D7, WinXP]
Есть новые Нет новых   [134437   +29][b:0][p:0.005]