How can two processes which bind on the same port receive the same message? - c++

I have two processes. both listen to the same port.
This is UDP multicast so both use the socket option SO_REUSEADDR, and join the multicast group prior to bind().
When I send a message to the multicast group ip:port only one of the processes gets the message.
How can both of them get it?
Thanks.

Two process can listen at the same port. Although two sockets for connections can't be bound to the same IP address with same port.
You just add an entry for each process in your hosts file that points to a unique ip address.
Something like :
You bind process P1 to 127.0.0.1 port 8080 and P2 to 127.0.0.2 port 8080.

I don't think it's possible, and I think that sometimes it is a lot more coherent this way.
Maybe you should implement a receiver (which will listen to the port) which will distribute the messages to the other processes via inter-processes communication (pipes for instance).

Related

Boost Asio UDP listening on all (or several) ports

Is it possible to have a boost asio udp client that is listening for messages on several ports at the same time? Or just listening for messages from any port?
For background (and because I am new to networking and probably not picking the best way to do this), essentially my problem is I have a main node kicking off processes on several other nodes in a cluster. When each child node finishes its process, it is to send it's results to another node that is waiting for results. I was thinking it would be easiest to simply do a UDP broadcast from each child node, with each child node broadcasting on a unique port, and the listener listening on all ports. Is there a better way to do this?
UDP sockets need to bind to a specific port if they have to receive incoming messages destined for that port. If you want to listen on a multiple of ports, then you will have to open multiple UDP sockets and bind them to all those ports. The bind method accepts the port number on which you wish to receive messages: http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/reference/basic_datagram_socket/bind/overload1.html

If you disable multicast loopback, can you send and receive on the same multicast group?

Imagine there is process A and processes B and C, and I want all of them to multicast out messages to group X.Y.Z.W on port P, and A is simultaneously listening to those messages on that group. Is it possible for A to receive the messages from B and C without receiving it's own? In other words, if I disable loopback (in order for A not to receive the messages it is multicasting) will it still receive the messages from B and C or will this effectively result in it no longer even listening to X.Y.Z.W on port P?
Yes, it will work as you describe. We're using this in RSP[1] in exactly the same way for any-to-any reliable multicast.
[1] http://www.equalizergraphics.com/documents/design/multicast.html#RSP
From what I can tell from the documentation, the IP_MULTICAST_LOOP option operates at the host level, not the individual socket. So if you disable it, no processes on the sending host will receive the multicast packets; if you enable it, all processes on the sending host will receive it.
What A can do is check the source IP and port of the packets it receives. If they match the local IP and port of its sending socket, it should ignore them.

Is it possible to bind and listen to one IP address with TCP/IP sockets? (Linux/C)

I have always used:
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
which means that I will accept connections from any interface. If I replace the INADDR_ANY with “192.168.0.1”. Does this mean I will only accept connections from the IP address of 192.168.0.1, or does it mean I will accept connections from the interface of 192.168.0.1 resides on?
I have a situation now where I have multiple clients (each with a unique IP address but same port number), trying to connect to one server. Can I have multiple listens functions (separate threads) listening to a unique IP address and port? Or do I have to accept any connection and get the network information after I've connected?
Edit To give more clarification.
If I say serv_addr.sin_addr.s_addr = inet_addr("192.168.0.1") and a client with IP address 192.168.0.2 tries to connect, will the listen command reject this?
The bind address is the local address to listen on; you can specify the address of a local interface.
If you want to control who can connect, you can either inspect the peer address inside the select/accept loop, or limit inbound connections using iptables.
Update
If I say serv_addr.sin_addr.s_addr = inet_addr("192.168.0.1") and a
client with IP address 192.168.0.2 tries to connect, will the listen
command reject this? I want to be able to have multiple thread, each
servicing a unique IP address.
No, the address is an address on a local machine. Given that you're going for a multi-threaded design, I'd recommend you run the listen/accept code in one thread, check the client address, decide what worker thread is appropriate, and then spawn it.
At the risk of showing my age, I still prefer using listen/accept/select for most socket code - it's a personal taste thing, and yes, does influence the design when it comes to blocking/non-blocking IO, buffering, etc.
If I replace the INADDR_ANY with “192.168.0.1”. Does this mean I will
only accept connections from the IP address of 192.168.0.1, or does it
mean I will accept connections from the interface of 192.168.0.1
resides on?
Yes
I have a situation now where I have multiple clients (each with a
unique IP address but same port number), trying to connect to one
server. Can I have multiple listens functions (separate threads)
listening to a unique IP address and port? Or do I have to accept any
connection and get the network information after I've connected?
Yes. You can "fork" (i.e. create a new thread) for each connection you wish to process, however you'd have to do the filtering yourself. There is no way (that I know off in the API) to offload that work to the stack.

Boost-asio listening to multiple IP Addresses on a single (TCP) acceptor

A boost TCP acceptor can be wired up by using an endpoint constructor that only takes a port number as it's argument, in which case it will listen to all IP addresses/NIC's.
Is it possible to get the acceptor to listen to select IP addresses ? Or will I have to create an acceptor for each IP address I am interested in ? Looking through the documentation I couldn't find any indications of this being a possibility.
I haven't looked at the socket API for a few years, but I guess the API doesn't directly allow this.
there's unbound listening and bound one. unbound means you listen to all NICs, bound - to specific one. There's no possibility to select some of NICs, I think because the same can be achived by dedicated acceptors for each of them

Connecting to a multicast server using actual IP and port of the server

I have a multicast server which multicast on an IP 233.1.2.8 on some ports
I need to connect to that server directly using its actual IP do not want to use the broadcast. I want to get actual data it sends on a specific port let say
Multicast Ip 233.1.2.8 port 32334 and 35245
Actual IP 198.122.55.191 port 35366
so i want to read the data of 35366
I can see that data in CommView.exe but can not read it if i try to connect it connects but no data
Thanks
You may want to rethink your question. IP packets have a source and destination address and port, so lets summarise:
You are looking for multicast packets with source port 35366.
Multicast address 233.1.2.8.
Destination port 32334 or 32335.
You will have to open two sockets, one listening to port 32334 and one to 32335, for each socket you will have to the multicast address 233.1.2.8. That gets you a stream of packets from any host, now you have a choice:
Use connect() to restrict to packets from 198.122.55.191.
Use recvmsg() or recvfrom() to read each packet with the source IP address and filter the stream within your application.
Use Source-Specific-Multicast (SSM) and subscribe to multicast address 233.1.2.8 from 198.122.55.191.
The last option usually requires IGMPv3 enabled network and is limited to 232.0.0.0/8 addresses.
Multicast by definition is one-way street: the server sends data to a group, and you subscribe to it.
Connecting to a server cannot be done through UDP, it requires a TCP server actually being there and listening for incoming connections on that particular port. The fact that that port is used for sending out multicast packets doesn't suggest that there's anyone listening on it as well.
If you want to read the data sent from a particular port - then you need to subscribe to all the groups, and analyze the UDP packets (and the IP frame if you have several servers transmitting, to know the origin IP) to see where they're coming from, and filter out the ones that come from the origin you fancy.
You can have a look at this site. It has an example also
http://tack.ch/multicast/