merijnb 4 Posted June 26, 2019 I'm trying to receive UDP packets which are sent to a multicast group. I can see the packets being received in WireShark (dest ip = 225.255.255.255 dest port = 1120), and can receive the data using an example python script I found on the net, meaning that UDP multicast group and port are correct. I'm creating an UDP server like this: var UDPServer: TWSocketServer; begin UDPServer := TWSocketServer.Create(Self); UDPServer.Proto := 'udp'; UDPServer.Addr := '0.0.0.0'; UDPServer.Port := '1120'; UDPServer.MultiCast := true; UDPServer.ReuseAddr := true; UDPServer.MultiCastAddrStr := '225.255.255.255'; UDPServer.OnDataAvailable := OnUDPDataAvailable; UDPServer.Listen(); end; The OnUDPDataAvailable is never called, am I missing something here in setting the server up properly to listen for this group? Share this post Link to post
Angus Robertson 574 Posted June 26, 2019 TWSocketServer is only for TCP, not UDP which does not have a concept of clients or connections. Change it to TWSocket. Not used multi casting for many years, but suspect that MultiCastAddrStr is for sending stuff, not receiving it. V8.60 added a new component TIcsIpStrmLog with a sample OverbyteIcsIpStmLogTst.dpr which has a logprotUdpServer mode that allows you to create a server with little code handling receiving data for you. Angus Share this post Link to post
merijnb 4 Posted June 26, 2019 3 hours ago, Angus Robertson said: TWSocketServer is only for TCP, not UDP which does not have a concept of clients or connections. Change it to TWSocket. Not used multi casting for many years, but suspect that MultiCastAddrStr is for sending stuff, not receiving it. V8.60 added a new component TIcsIpStrmLog with a sample OverbyteIcsIpStmLogTst.dpr which has a logprotUdpServer mode that allows you to create a server with little code handling receiving data for you. Angus Tx for the wonderful quick reply. I've looked at TIcsIpStrmLog but there is no use of multicast in there. With regard to MultiCastAddrStr being for sending only I'm quite sure it's not. I've found several places where it's mentioned that to use multicast listening it's required to call setsockopt() with IP_ADD_MEMBERSHIP to 'register' the multicast group you want to listen to with the kernel, the working piece of Python code also does something similar. Other places this is mentioned are for example: https://stackoverflow.com/questions/43322462/multicast-packet-seen-in-wireshark-but-not-received-by-user-program-windows-an and http://www.tldp.org/HOWTO/Multicast-HOWTO-6.html There is something in the ICS wiki about receiving multicast data: WS.Proto:='udp'; WS.Addr:='192.168.0.1'; // IP address of the physical adapter I want to bind to WS.Port:='5000'; WS.MultiCast:=true; WS.ReuseAddr:=true; WS.MultiCastAddrStr:='239.192.1.1'; // Mutlicast IP WS.Listen; (from http://wiki.overbyte.eu/wiki/index.php/TWSocket.MultiCast) I also see something like that in OverbyteIcsWsocket: if FMultiCast then begin if FAddrFormat = AF_INET then begin { Use setsockopt() to join a multicast group } { mreq.imr_multiaddr.s_addr := WSocket_inet_addr('225.0.0.37');} { mreq.imr_multiaddr.s_addr := sin.sin_addr.s_addr;} { mreq.imr_multiaddr.s_addr := WSocket_inet_addr(FAddrStr);} mreq.imr_multiaddr.s_addr := WSocket_Synchronized_inet_addr(PAnsiChar(AnsiString(FMultiCastAddrStr))); { mreq.imr_interface.s_addr := htonl(INADDR_ANY);} { RK} mreq.imr_interface.s_addr := WSocket_Synchronized_ResolveHost(AnsiString(FAddrStr)).s_addr; iStatus := WSocket_Synchronized_SetSockOpt(FHSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, @mreq, SizeOf(mreq)); if iStatus <> 0 then begin SocketError('setsockopt(IP_ADD_MEMBERSHIP)'); Exit; end; So I'm quite sure that it's required for receiving multicast data, but for some reason I'm not receiving anything, as if the implementation in the last snippet has something wrong. Do we know who is the author of this snippet? Thanks again! Share this post Link to post
Remy Lebeau 1396 Posted June 26, 2019 (edited) In addition to what has already been said, 255.255.255.255 is not a valid Multicast group IP, it is a UDP subnet broadcast IP. Subnet broadcasts are very different than Multicast broadcasts. Valid multicast group IPs (for IPv4) are in the range of 224.0.0.0 to 239.255.255.255. Edited June 26, 2019 by Remy Lebeau Share this post Link to post
merijnb 4 Posted June 27, 2019 (edited) 9 hours ago, Remy Lebeau said: In addition to what has already been said, 255.255.255.255 is not a valid Multicast group IP, it is a UDP subnet broadcast IP. Subnet broadcasts are very different than Multicast broadcasts. Valid multicast group IPs (for IPv4) are in the range of 224.0.0.0 to 239.255.255.255. Hi Remy, Thanks, but I realize that, but the multicast group ip being used is 225.255.255.255 (easy to overlook that 🙂 ) Edited June 27, 2019 by merijnb Share this post Link to post
Angus Robertson 574 Posted June 27, 2019 Sorry can not really help any further, I think my last UDP project was just broadcasting not multicasting. I would test keeping things simple, ignore multicast completely, just a simple UDP listener and see what happens. Your can use the OverbyteIcsIpStmLogTst sample to send normal UDP packets to make sure your server is receiving something, then look into why multicast is not working. Angus Share this post Link to post
merijnb 4 Posted June 27, 2019 38 minutes ago, Angus Robertson said: Sorry can not really help any further, I think my last UDP project was just broadcasting not multicasting. I would test keeping things simple, ignore multicast completely, just a simple UDP listener and see what happens. Your can use the OverbyteIcsIpStmLogTst sample to send normal UDP packets to make sure your server is receiving something, then look into why multicast is not working. Angus UDP singlecast and broadcast is working fine (I've done that many times), this is the first time I need to use multicast though and it behaves a little bit differently internally (the whole IP_ADD_MEMBERSHIP thing). I respect you (Angus) can't help me though, any other takers? Or do we know who wrote this part in ICS originally? Share this post Link to post
Angus Robertson 574 Posted June 27, 2019 There are two names for contributors that worked on multicast in the release notes, but they were almost 20 years ago. Angus Share this post Link to post
Dave Nottage 557 Posted June 27, 2019 I managed to make UDP multicast work to my satisfaction (with both IPv4 and IPv6) with Indy a while ago.. had to jump through a bunch of hoops to make it happen. My work has been "sitting on a shelf" waiting for funding for the project(s) it may be used in, but I could turn it into some building blocks for anyone who's interested. One of the things I had to overcome was the lack of multiple bindings in TIdIPMCastServer - a pretty basic omission. Others were: local address changes (because of one or more networks being unavailable etc), dealing with IPv6 only networks (a must for iOS), and discovering local addresses on Android (which Indy does not do yet, unless it has changed recently) I've tried a number of network libraries including ICS, but Indy is still the least painful to work with. Much kudos to Remy. Share this post Link to post
merijnb 4 Posted June 27, 2019 Hey Dave, I'm not going to switch from ICS to Indy, but with your experience with getting receiving multicast, can you see if there is anything wrong with the snippet from ICS above, or can you see if there is anything missing? Is calling setsocktopt with IP_ADD_MEMBERSHIP what needs to be done? Share this post Link to post
Angus Robertson 574 Posted June 27, 2019 If multicast needs to listen on multiple UDP ports and/or addresses, just create an array of TWSocket components with different IP addresses/ports for each, sharing the same event handlers. For TCP we already have TMultiListenWSocketServer which is the same as TWSocketServer so web servers listen on lots of ports and IPv4 and IPv6 at the same time. Angus Share this post Link to post
merijnb 4 Posted June 27, 2019 10 minutes ago, Angus Robertson said: If multicast needs to listen on multiple UDP ports and/or addresses, just create an array of TWSocket components with different IP addresses/ports for each, sharing the same event handlers. For TCP we already have TMultiListenWSocketServer which is the same as TWSocketServer so web servers listen on lots of ports and IPv4 and IPv6 at the same time. Angus The issue currently is not listening on multiple ports and / or addresses, receiving multicast data on a single ip and port doesnt' work either. It seems to be with the fact that you need to register with the kernel what unicast groups you want to listen to, otherwise the datagrams aren't even passed to your process. Share this post Link to post
HolgerX 7 Posted June 27, 2019 Hmm.. I am not using ICS, but I have a small testtool for MultiCast made with INDY 10. It's done with D6, but you could use it for a local test... (Indy 10 is only in the search path, not added to the zip.. 😉 ) Test_INDY_Multicast.zip 1 Share this post Link to post
Remy Lebeau 1396 Posted June 28, 2019 (edited) On 6/27/2019 at 12:14 AM, merijnb said: Thanks, but I realize that, but the multicast group ip being used is 225.255.255.255 (easy to overlook that 🙂 ) Like I said earlier, 255.255.255.255 is not a valid multicast group IP. If that is what you are seeing being used on the network, then it is not multicast to begin with. Where EXACTLY are you seeing that? Edited June 28, 2019 by Remy Lebeau Share this post Link to post
Hallvard Vassbotn 3 Posted June 29, 2019 Remy, the first byte is 225, not 255..:) Share this post Link to post
Remy Lebeau 1396 Posted June 29, 2019 11 hours ago, Hallvard Vassbotn said: Remy, the first byte is 225, not 255..:) Good catch. VERY hard to see that... 1 Share this post Link to post
Dave Nottage 557 Posted July 18, 2019 On 6/27/2019 at 8:53 PM, Dave Nottage said: My work has been "sitting on a shelf" waiting for funding for the project(s) it may be used in, but I could turn it into some building blocks for anyone who's interested. Well, it has now come "off the shelf", however not so good news: I'm now unable to make it receive on anything other than Windows (tried iOS, macOS and Android). Sending works from any platform. I swear it was all working before. In any event, I've now made it public, here: https://github.com/DelphiWorlds/Multicaster Share this post Link to post