I am experimenting with IP multicasting in Ada, but doesn't seem to receive any traffic sent to the multicast group. Somehow, it seems like I cannot get the application to fetch the incoming packets.
I can verify (using Wireshark) that a multicast join is sent from my computer, and also I can verify that there is data being sent to the multicast group.
I can verify that OS has the multicast join registered by the netsh command:
netsh interfaces ip show joins
My group is listed with a reference of 1 if I run my program and 0 if it is not.
The following procedure shows my listener, and I invoke it using Mcast_IP => "239.255.128.128"
and Mcast_Port => "8807"
:
with GNAT.Sockets;
with Ada.Streams;
with Ada.Text_IO;
procedure Receive_Multicast (Mcast_IP : in String;
Mcast_Port : in String)
is
package GS renames GNAT.Sockets;
package AS renames Ada.Streams;
package Tio renames Ada.Text_IO;
use GS;
use type Ada.Streams.Stream_Element_Offset;
Socket : GS.Socket_Type;
Address : GS.Sock_Addr_Type;
Data : AS.Stream_Element_Array (1 .. 2**16);
Offset : AS.Stream_Element_Offset;
Sender : GS.Sock_Addr_Type;
begin
Address.Addr := Any_Inet_Addr;
Address.Port := Port_Type'Value (Mcast_Port);
Create_Socket (Socket => Socket,
Family => Family_Inet,
Mode => Socket_Datagram);
Bind_Socket (Socket, Address);
-- Set socket options
Set_Socket_Option (Socket,
Socket_Level,
(Reuse_Address, True));
Set_Socket_Option
(Socket,
IP_Protocol_For_IP_Level,
(Multicast_TTL, 1));
Set_Socket_Option
(Socket,
IP_Protocol_For_IP_Level,
(Multicast_Loop, True));
Set_Socket_Option
(Socket,
IP_Protocol_For_IP_Level,
(Add_Membership, Inet_Addr (Mcast_IP), Any_Inet_Addr));
Tio.Put_Line ("Listening for MULTICASTS on port " & Address.Port'Img);
-- Receive the packet from the socket.
loop
Tio.Put_Line ("Waiting for incoming packets...");
Receive_Socket (Socket => Socket,
Item => Data,
Last => Offset,
From => Sender);
Tio.Put_Line ("Received " & Offset'Img & " bytes.");
end loop;
end Receive_Multicast;
The procedure works its way down to the Receive_Socket
call (which is a procedure in GNAT.Sockets
package). However, even if I can confirm multicast traffic using Wireshark, the call to Receive_Socket
keeps blocking.
UPDATE/SOLUTION:
The code above does actually work, although I had to completely uninstall Kaspersky which apparently did prevent multicasts sent from my own machine to be received (i.e. loopback). The accepted answer does also work flawlessly.