The question is tagged with Ada, since I need to code it in Ada. However, the problem is language independent.
I am in a situation where I have this network configuration. This is a given constraint, it cannot be changed for now.
- 192.168.0.2
- Emits UDP with broadcast : 224.224.0.1
- on ports A and B
- 192.168.0.3
- Emits UDP with broadcast : 224.224.0.2
- on ports A and B
I need to write a piece of software running on 192.168.0.1
that is able to receive data from one or the other.
What I tried so far :
- Create 2 sockets bound to 192.68.0.2 + ports. Same if I want the other 2 sockets for 192.68.0.3).
This does not work. I get socket error 10049 can't assign address
(see https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx)
I've read this : What does it mean to bind a multicast (UDP) socket?. So I tried to switch to "Any".
- Create 2 sockets bound to Any + relevant port (A and B)
This works, I can listen to anyone, but I can't tell who's talking to me. For small tests, it works. But I'll get into trouble when I'll have the second emitter involved.
-- emitter uses multicast
GNAT.Sockets.Set_Socket_Option (Socket => socket_data.Socket,
Level => GNAT.Sockets.IP_Protocol_For_IP_Level,
Option => (Name => GNAT.Sockets.Add_Membership,
Multicast_Address => GNAT.Sockets.Inet_Addr (SERVER_MULTICAST_EMISSION_IP),
Local_Interface => GNAT.Sockets.Any_Inet_Addr));
Print ("Configure Receive socket - IP_Protocol_For_IP_Level Multicast_Address OK");
GNAT.Sockets.Set_Socket_Option (socket_data.Socket,
GNAT.Sockets.IP_Protocol_For_IP_Level,
(GNAT.Sockets.Multicast_Loop, True));
Print ("Configure Receive socket - IP_Protocol_For_IP_Level Multicast_Loop OK");
GNAT.Sockets.Set_Socket_Option (Socket => socket_data.Socket,
Option => (Name => GNAT.Sockets.Receive_Timeout,
Timeout => GNAT.Sockets.Timeval_Duration (0.03)));
Print ("Configure Receive socket - timeout OK");
-- bind to address+port
GNAT.Sockets.Bind_Socket (Socket => socket_data.Socket,
Address => socket_data.Bound_To_Address);
My question is simple :
I feel that there is something wrong in my issue : having 2 emitters in broadcast on same ports make the filtering from the reception side a bit... tricky
On my machine 192.168.0.1, why can't I create the socket 192.168.0.2:A/192.168.0.2:B and bind to it ?
If I'm stuck with the "any" solution, how can I configure/program my sockets to filter out the emitter IP ?
(As mentioned aboved, I have already read the reference answers on sockets What does it mean to bind a multicast (UDP) socket? and Socket options SO_REUSEADDR and SO_REUSEPORT, how do they differ? Do they mean the same across all major operating systems?)