Hi Emanuele,

Thanks for the examples

I actually have a working application with multicast, but I was wondering if it was correct, because I tested it with a switch that manages IGMP and no multicast groups were being created.

I saw that you set TTL to 32, why? The default 1 would not work? I know that 1 would work just on local network (My case)

What I´m confused is with the group creation, how my ICS based application with create a multicast group that is visible for switches (By using IGMP) and switches can manage this multicast distribution? Without that, multicast would be just like broadcast.

I saw on TWSocket source that when I start listening it actually sets the socket to ADD_MEMBERSHIP tp the group, this may be OK for receiving data, but I´m confused about sending multicast data, because the sender is the one that was supposed to create the multicast group right? But to send multicast data on network I need to use Connect method instead of Listen from the TWSocket, in this case, on Connect method I didn´t find a mention to ADD_MEMBERSHIP or creating a multicast group.

Thanks
Eric


-----Mensagem Original----- From: emanuele bizzarri
Sent: Thursday, May 26, 2011 3:41 AM
To: twsocket@elists.org
Subject: Re: [twsocket] Multicast question

Hi,
this is an example of TUDP class that can be used in multicast (receive
and transmit).
This unit depends by other units, but you can easily extract what you need.
Note that I set multicast ttl.
I hope it will be usefull for you,
Bye
Emanuele


unit ewPlatform_UDP;

interface

uses
 ewPlatform_Lists,
 ewPlatform_Logger,
 ewPlatform_Memory,
 ewPlatform_Packets,
 ewPlatform_Strings,
 OverByteIcsWsocket,
 WinSock,
 Windows,
 SysUtils,
 Classes;

type
 TOnUDPError=procedure(aError:integer)of object;
 TOnUDPDataSent=procedure(aInteger:integer)of object;

TOnUDPDataAvailable=procedure(aSender:TObject;aData:pointer;aSize:integer;aPeerIP:string;aPeerPort:integer)
of object;
 TUDP=class
 protected
   fWS:TWSocket;
   fSent:boolean;
   fPeerSrc:TSockAddr;
   fPeerSrcLen:integer;
   fRxData:pointer;
   fRxSize:integer;
   fWhiteList:TStringList;
   fBlackList:TStringList;
   fTxList:TStringList;
   procedure DataAvailable(aSender:TObject;aError:word);
   procedure DataSent(aSender:TObject;aErrCode:word);
   procedure DnsLookupDone(aSender:TObject;aErrCode:word);
   procedure ChangeState(aSender:TObject;aOldState,aNewState:TSocketState);
   procedure Send;
   function GetStarted:boolean;
 public
   pLocalIP:string;
   pLocalPort:integer;
   pPeerIP:string;
   pPeerPort:integer;
   pMultiThreaded:boolean;
   pMulticast:boolean;
   pUseWhiteList:boolean;
   pUseBlackList:boolean;
   pMulticastTTL:integer;

   pGetPeerByData:boolean;
   pOnDataSent:TOnUDPDataSent;
   pOnDataAvailable:TOnUDPDataAvailable;
   pOnError:TOnUDPError;
   pOnChangeState:TChangeState;

   constructor Create;
   destructor Destroy;override;
   procedure StartRx;
   procedure SetTx;
   procedure Disconnect;
   procedure Connect;
   function Add2WhiteList(aIPPort:string):boolean;
   function Add2BlackList(aIPPort:string):boolean;
   procedure DeleteFromWhiteList(aIPPort:string);
   procedure DeleteFromBlackList(aIPPort:string);
   procedure ClearWhiteList;
   procedure ClearBlackList;
   function NewData(aData:pointer;aSize:integer):integer;

   property pStarted:boolean read GetStarted;

   end;

implementation

//------------------------------------------------------------------------------
//TUDP
//------------------------------------------------------------------------------
constructor TUDP.Create;
begin
 inherited Create;
 TLogger.Log('UDP socket creation
threadID='+inttostr(GetCurrentThreadID),lsVerbose,true);
 fWS:=TWSocket.Create(nil);
 fWS.OnDataAvailable:=DataAvailable;
 fWS.OnDataSent:=DataSent;
 fWS.OnDnsLookupDone:=DnsLookUpDone;
 fWS.OnChangeState:=ChangeState;
 fWS.Proto:='udp';

 pGetPeerByData:=false;
 fTxList:=TStringList.Create;
 fSent:=false;

 pLocalIP:='0.0.0.0';
 pLocalPort:=0;
 pPeerIP:='';
 pPeerPort:=0;
 pMultiThreaded:=false;
 pMulticast:=false;
 pMulticastTTL:=32;

 fWhiteList:=TStringList.Create;
 fBlackList:=TStringList.Create;
 pUseWhiteList:=false;
 pUseBlackList:=false;

 fRxSize:=256*1024;
 getmem(fRxData,fRxSize);

 fPeerSrcLen:=sizeof(fPeerSrc);
end;

destructor TUDP.Destroy;
begin
 Disconnect;
 FreeObjAndNil(fWS);
 FreeMemAndNil(fRxData);
 FreeObjAndNil(fWhiteList);
 FreeObjAndNil(fBlackList);
 FreeList(fTxList);
 FreeObjAndNil(fTxList);
 inherited Destroy;
end;

procedure TUDP.StartRx;
begin
 Disconnect;
 pLocalIP:=trim(pLocalIP);
 if (pLocalIP<>'')and(pLocalPort>0) then
 begin
   fWS.Proto:='udp';
   fWS.MultiThreaded:=pMultiThreaded;
   fWS.Addr:=pLocalIP;
   fWS.Port:=inttostr(pLocalPort);
   if fWS.Addr='' then
     fWS.Addr:='0.0.0.0';
   if pMulticast then
   begin
     fWS.MultiCast:=true;
     fWS.ReuseAddr:=true;
     fWS.MultiCastAddrStr:=pPeerIP;
   end;
   fWS.Listen;
   fWS.SocketRcvBufSize:=fRXSize;
   if pMulticast then

setsockopt(fWS.HSocket,IPPROTO_IP,IP_MULTICAST_TTL,@pMulticastTTL,sizeof(pMulticastTTL));
 end
 else
   TLogger.Log('UDP socket start rx error LocalIP='+pLocalIP+'
LocalPort='+inttostr(pLocalPort),lsError,true);
end;

function TUDP.GetStarted:boolean;
begin
 result:=false;
 if (assigned(fWS)) then
   result:=(fWS.State=wsListening)or(fWS.State=wsConnected);
end;

procedure TUDP.SetTx;
var
 lRes:boolean;
begin
 pPeerIP:=trim(pPeerIP);
 lRes:=(pPeerIp<>'')and(pPeerPort>0);
 TLogger.Log('UDP socket set tx PeerIP='+pPeerIP+'
PeerPort='+inttostr(pPeerPort)+'...
'+Boolean2Str(lRes,'ok','ko'),Boolean2Severity(lRes,lsVerbose,lsError),true);
 fPeerSrc.sin_family:=AF_INET;
 fPeerSrc.sin_addr.s_addr:=WSocket_inet_addr(AnsiString(pPeerIP));
 fPeerSrc.sin_port:=htons(word(pPeerPort));
 fSent:=false;
 FreeList(fTxList);
end;

procedure TUDP.Disconnect;
begin
 fWS.Shutdown(SD_BOTH);
 fWS.Close;
 FreeList(fTxList);
 fSent:=false;
end;

procedure TUDP.Connect;
begin
 Disconnect;
 fWS.Proto:='udp';
 fWS.MultiThreaded:=pMultiThreaded;
 fWS.LocalAddr:=pLocalIP;
 fWS.Addr:=trim(pPeerIP);
 fWS.Port:=inttostr(pPeerPort);
 SetTx;
 if (fWS.Addr<>'')and(pPeerPort>0) then
   fWS.DnsLookup(fWS.Addr);
end;

procedure TUDP.DnsLookupDone(aSender:TObject;aErrCode:word);
begin
 //se riesco a risolvere l'host mi connetto
 if aErrCode=0 then
 begin
   fWS.Connect;
   fWS.SocketRcvBufSize:=fRXSize;
 end;
end;

procedure
TUDP.ChangeState(aSender:TObject;aOldState,aNewState:TSocketState);
begin
 if assigned(pOnChangeState) then
   pOnChangeState(self,aOldState,aNewState);
end;

function TUDP.NewData(aData:pointer;aSize:integer):integer;
var
 lItem:TBufferItem;
begin
 result:=0;
 if (pPeerIP<>'')and(GetStarted) then
 begin
   lItem:=TBufferItem.Create(aData,aSize,0,0);
   fTxList.AddObject(inttostr(aSize),lItem);
   Send;
 end;
end;

procedure TUDP.Send;
var
 lItem:TBufferItem;
begin
 if (not fSent)and(fTxList.Count>0) then
 begin
   lItem:=TBufferItem(fTxList.Objects[0]);
   if (fWS.SendTo(fPeerSrc,fPeerSrcLen,lItem.pData,lItem.pSize)>0)or
      (WSocket_WSAGetLastError=WSAEWOULDBLOCK)
   then
     fSent:=true;
 end;
end;

procedure TUDP.DataSent(aSender:TObject;aErrCode:word);
var
 lItem:TBufferItem;
 lSize:integer;
begin
 if fSent then
 begin
   fSent:=false;
   lSIze:=0;
   if fTxList.Count>0 then
   begin
     lItem:=TBufferItem(fTxList.Objects[0]);
     if assigned(lItem) then
     begin
       lSize:=lItem.pSize;
       FreeObjAndNil(lItem);
     end;
     fTxList.Delete(0);
   end;
   if assigned(pOnDataSent) then
     pOnDataSent(lSize);
   Send;
 end;
end;

procedure TUDP.DataAvailable(aSender:TObject;aError:word);
var
 lSize:integer;
 lPeerSrc:TSockAddrIn;
 lPeerSrcLen:integer;
 lPeerIP:string;
 lPeerPort:integer;
 lValidPeer:boolean;
begin
 lPeerSrcLen:=sizeof(lPeerSrc);
 lSize:=fWS.ReceiveFrom(fRxData,fRxSize-2,lPeerSrc,lPeerSrcLen);
 if lSize<0 then
 begin
   {
   WSAEWOULDBLOCK=10035
   Resource temporarily unavailable.
   This error is returned from operations on nonblocking sockets that
cannot
   be completed immediately, for example recv when no data is queued to be
   read from the socket. It is a nonfatal error, and the operation
should be
   retried later. It is normal for WSAEWOULDBLOCK to be reported as the
   result from calling connect on a nonblocking SOCK_STREAM socket,
   since some time must elapse for the connection to be established.
   }
   {
   WSAECONNRESET=10054
   Connection reset by peer.
   An existing connection was forcibly closed by the remote host. This
normally
   results if the peer application on the remote host is suddenly stopped,
   the host is rebooted, the host or remote network interface is disabled,
   or the remote host uses a hard close (see setsockopt for more
   information on the SO_LINGER option on the remote socket). This
error may
   also result if a connection was broken due to keep-alive activity
detecting a
   failure while one or more operations are in progress. Operations that
   were in progress fail with WSAENETRESET. Subsequent operations
   fail with WSAECONNRESET.
   }
   if assigned(pOnError) then
     pOnError(WSocket_WSAGetLastError);
 end
 else
 begin
   lPeerIP:=string(AnsiString(inet_ntoa(lPeerSrc.sin_addr)));
   lPeerPort:=ntohs(lPeerSrc.sin_port);

   if pGetPeerByData then
   begin
     pGetPeerByData:=false;
     pPeerIP:=lPeerIP;
     pPeerPort:=lPeerPort;
     SetTx;
   end;
   lValidPeer:=true;
   if pUseWhiteList then
   begin

lValidPeer:=(fWhiteList.IndexOf(lPeerIP+':'+inttostr(lPeerPort))>=0)or(fWhiteList.IndexOf(lPeerIP+':*')>=0);
   end;
   if (lValidPeer)and(pUseBlackList) then

lValidPeer:=(fBlackList.IndexOf(lPeerIP+':'+inttostr(lPeerPort))<0)and(fBlackList.IndexOf(lPeerIP+':*')<0);
   if lValidPeer then
   begin
     PAnsiChar(fRxData)[lSize]:=#0;
     PAnsiChar(fRxData)[lSize+1]:=#0;
     if assigned(pOnDataAvailable) then
       pOnDataAvailable(self,fRxData,lSize,lPeerIP,lPeerPort);
   end;
 end;
end;

function TUDP.Add2WhiteList(aIPPort:string):boolean;
begin
 result:=false;
 DeleteFromBlackList(aIPPort);
 if fWhiteList.IndexOf(aIPPort)<0 then
 begin
   fWhiteList.Add(aIPPort);
   result:=true;
 end;
end;

function TUDP.Add2BlackList(aIPPort:string):boolean;
begin
 result:=false;
 DeleteFromWhiteList(aIPPort);
 if fBlackList.IndexOf(aIPPort)<0 then
 begin
   fBlackList.Add(aIPPort);
   result:=true;
 end;
end;

procedure TUDP.DeleteFromWhiteList(aIPPort:string);
var
 lIndex:integer;
begin
 lIndex:=fWhiteList.IndexOf(aIPPort);
 if lIndex>=0 then
   fWhiteList.Delete(lIndex);
end;

procedure TUDP.DeleteFromBlackList(aIPPort:string);
var
 lIndex:integer;
begin
 lIndex:=fBlackList.IndexOf(aIPPort);
 if lIndex>=0 then
   fBlackList.Delete(lIndex);
end;

procedure TUDP.ClearWhiteList;
begin
 fWhiteList.Clear;
end;

procedure TUDP.ClearBlackList;
begin
 fBlackList.Clear;
end;

end.

Il 26/05/2011 06:48, Éric Fleming Bonilha ha scritto:
Hi

I´m wondering how to use ICS properly to send and receive Multicast data. Where can I find example for multicast and ICS?

I´m in doubt about the IGMP protocol, do I need to implement anything on application layer or does IGMP protocol is implemented on underlying stack automatically?

How my application will create a multicast group on network and/or join a group?

Thank you very much!
Eric
--
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

--
Ing. Emanuele Bizzarri
Software Development Department
e-works s.r.l.
41011 - Campogalliano - Modena - Italy
tel. +39 059 2929081 int. 23
fax +39 059 2925035

e-mail: e.bizza...@e-works.it - http://www.e-works.it
---------------------------------------------------------------------
La presente comunicazione, che potrebbe contenere informazioni riservate
e/o protette da segreto professionale, è indirizzata esclusivamente ai
destinatari della medesima qui indicati. Le opinioni, le conclusioni e
le altre informazioni qui contenute, che non siano relative alla nostra
attività caratteristica, devono essere considerate come non inviate né
avvalorate da noi. Tutti i pareri e le informazioni qui contenuti sono
soggetti ai termini ed alle condizioni previsti dagli accordi che
regolano il nostro rapporto con il cliente. Nel caso in cui abbiate
ricevuto per errore la presente comunicazione, vogliate cortesemente
darcene immediata notizia, rispondendo a questo stesso indirizzo di
e-mail, e poi procedere alla cancellazione di questo messaggio dal
Vostro sistema. E' strettamente proibito e potrebbe essere fonte di
violazione di legge qualsiasi uso, comunicazione, copia o diffusione dei
contenuti di questa comunicazione da parte di chi la abbia ricevuta per
errore o in violazione degli scopi della presente.
---------------------------------------------------------------------
This communication, that may contain confidential and/or legally
privileged information, is intended solely for the use of the intended
addressees. Opinions, conclusions and other information contained in
this message, that do not relate to the official business of this firm,
shall be considered as not given or endorsed by it. Every opinion or
advice contained in this communication is subject to the terms and
conditions provided by the agreement governing the engagement with such
a client. If you have received this communication in error, please
notify us immediately by responding to this email and then delete it
from your system. Any use, disclosure, copying or distribution of the
contents of this communication by a not-intended recipient or in
violation of the purposes of this communication is strictly prohibited
and may be unlawful.

--
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be
--
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to