Il 26/05/2011 15:28, Éric Fleming Bonilha ha scritto: > 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)
I used multicast on wan. Our customer wanted this setting. > > 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. > Using wireshark, when a multicast socket enter in listening state, you should see igmp packets on the net. These packets should tell to the switch how to manage multicast distribution. > 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. In my implementation, I start listening also for the sender, using TUDP.SetTx and TUDP.StartRx methods. I use TUDP.Connect method, only for send udp unicast packets. I'm not a multicast expert. I found this kind of solution that worked in my scenario. Using my implementation, what kind of packet distribution do you get? Broadcast? Bye > > 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