My application uses LWIP 1.4.1. I’m trying to receive data on several multicast sockets at once. It all works, except for one issue which I can’t yet explain.
I’ve got three sockets:
Socket A: 22.214.171.124:5000
Socket B: 126.96.36.199:5000
Socket C: 188.8.131.52:6002
Socket A and Socket B are never open at the same time; there is a user input which switches between socket A and B, so when one closes the other opens. Socket C is initialised once and is then always open. My intention is to send individual
streams of data to each socket and have each socket individually receive the data for its own multicast address + port combination only.
What I’ve found is, if I send data on 184.108.40.206:5000 intended for Socket A only, then it is received by socket A. If I then switch to socket B, that socket ALSO receives the data for Socket A! If I switch back to socket A then the data
is received as normal. If I send data for socket B then only socket B picks up that data and not socket A.
If I do not initialise socket C then socket A and socket B work as intended, i.e. they only receive data on their respective multicast address + port combination. Similarly, if I initialise socket C but use a totally unique socket/address
combination, e.g. 220.127.116.11:7000 then socket A and socket B work fine. So it’s as if the overlap of ports and address between sockets is causing socket B to pick up data not intended for it.
I initialise each socket as follows (error checking has been removed for simplicity):
#define NUMTHREADS 13
struct ip_mreq mreq[NUMTHREADS];
int initSocket(int thread_index)
//Make a socket
sock_id = socket(AF_INET, SOCK_DGRAM, 0);
//Initialise RX struct
memset(&ra, 0, sizeof(struct sockaddr_in));
ra.sin_family = AF_INET;
ra.sin_addr.s_addr = htonl(INADDR_ANY);
ra.sin_port = htons(channel[thread_index].port); //e.g. 5000
//Join Multicast group (as configured)
mreq[thread_index].imr_multiaddr.s_addr = inet_addr(channel[thread_index].ipv4_address); //e.g. 18.104.22.168
mreq[thread_index].imr_interface.s_addr = htonl(INADDR_ANY);
//Add to multicast group
ret = setsockopt(sock_id, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq[thread_index], sizeof(mreq[thread_index]));
//bind RX struct to socket
ret = bind(sock_id, (struct sockaddr *)&ra, sizeof(ra));
And then to receive the data:
ret = recv(sock_id, packet[thread_index], 92, 0);
Is this the correct way to initialise sockets for my purpose?
I’ll start looking at the LWIP code just in case there’s a bug, but I was hoping I’d just done something wrong and there’s an obvious answer?
Software Applications Engineer
GAI-Tronics Brunel Drive
Stretton Business Park
Burton upon Trent
+44 (0) 1283 500500 (ext 274)