How to determine sender's mulicast group&port pair from the received multicast message - c++

I have written a service (C++) that runs on the AIX machine and receives Multicast messages from a remote host (my service joins a predefined Multicast group&port pair).
Lately, I've been asked to handle the Multicast messages received from a different host (on a different Multicast group&port, on the same socket. Though I can insist on the same port.
The issue is, that the messages received from each host must be handled differently.
How do I distinguish between these messages? Is there a possibility to retrieve the sender's Multicast group&port pair from the socket/received messages?

While you can identify the remote host's address (not multi-cast group!) with recvfrom(); it's generally not a good idea to perform different actions for different host with listening same port. It's against the rule of least surprise.
So the short answer is to differentiate remote host address.
If you want to differentiate multi-cast groups on the same port, you have to bind multiple sockets with the multi-cast group address.
The code looks like this:
addr.set(239,0,0,1,8888);
udp.socket();
udp.joinmcast(&addr);
udp.bind(&addr);

Related

How Do I Send Data From One Computer To Another Without A Server (in C++)?

so I want to send an int32 (or any 4 bytes data) from one pc to another, the size of the data will always be the same, I don't need any checking to see if both pcs are online or any disconnect function, if pc2 didn't receive the data or he went offline, I just want pc1 to send the data, if pc2 is offline nothing happens and if it's online it store it somewhere.
Most tutorials I've found uses a server way of connecting, so there are 3 pcs, 2 clients and 1 server, client1 sends data to the server and the server sends it to client2, but is there a way to send it directly to client2, as if client2 is the server?
There are two common protocols used to send raw data over an ip based network. They are called TCP and UDP and serve slightly different approaches.
TCP is connection oriented and relies heavily on the server client model. On host acts as a server and accepts incoming requests on a predefined socekt. After the TCP connection is setup, you have a duplex (two-way) stream that you can use to exchange data.
UDP is a packet oriented protocol. One host (usually called the server) listens to imcoming packets and can answer them. No real "connection" is established tough.
You probably want to use UDP. Note that altough this protocol does not establish a connecion, there still needs to be at least one host, that is waiting for incoming data on a predefined port. This one is usually called the "server". However also the client can bind its UDP socket to a specific port and thus can act as a "client" and a "server" during the same time.
You can setup both hosts to listen and send on/to the same preefined port number and achieve a connectionless packetoriented way to exchange data. That way both hosts act as server and client simultaneously.
How you actually implement this, depends on your operating system. On Linux (and other POSIX compatible OSes) you can use standard UDP sockets, on Windows there is some equivalent API. Either way I suggest you to first follow a tutorial on how to program a standard TCP server and client, as most of the operations on the sockets are similar (create the socket, bind it to an address:port, and read/write data from it).

How to find the destination address of a UDP packet using boost::asio?

I'm developing a peer-to-peer communications network for use over a LAN in an industrial environment. Some messages are are just asynchronous, and don't require a response. Others are request-response. The request messages (and the async messages) are sent to a multicast group, and the replies to requests are sent unicast. Each endpoint, therefore, receives UDP packets that are sent to the multicast group, and also receives messages that are just sent to it using plain unicast.
So far it's working fine, but there doesn't seem to be any way in boost::asio to find out the destination address of a received UDP packet (using socket.async_receive_from) - whether it was sent to the multicast group or the actual interface. I can use the contents of the message to infer whether it was sent multicast or unicast, but it would be nice to be able to also check the destination address.
We are currently using Windows 7, but will be transitioning to Linux in the future.
Is there a way to find the destination address of a UDP packet received using boost::asio?
Unfortunately this is not possible with boost::asio, and usually is not "the way to do" it, as you try to access Transport Layer information at the Application Layer.
So you basically have two options:
a) Write non-portable system code with for example IP_PKTINFO or SO_BINDTODEVICE on Linux. Example Code can be found on the boost asio mailing list here
b) use two distinct sockets, one for the multicast and one for the unicast. You therefore need to specify a listen_address other than "0.0.0.0" on each socket.
udp::endpoint(address_v4::from_string("239.192.152.143"), 6771)
This Question on SO might also be helpful: Using a specific network interface for a socket in windows

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.

Find all clients in network

I'm writing client-server application and I need my server to find all clients in some network. I've already found some info here: Discovering clients on a wifi network, but I still don't understand how to implement this. Maybe somebody can say where I can find some code examples.
Thanks in advance.
PS. Working on c++, windows.
Generally TCP/IP is used as a communication protocol between client and server. For Windows platform Winsock library is used to implement TCP/IP. The server binds and listens on a port for incoming connections. Just like a webserver like stackoverflow listens by default on port 80 and then client (browsers) connects to it.
Here is a link to start. Here is sample
Normally all the client connects to server which listens on a well defined port. The server is only one hence the IP address and port is well know to all the client and hence they can connect to it.
In you case you want your server to have ablity to discover all the clients in the network. To achieve this the server needs to broadcast to network some message. The client will receive this message and will respond to the server that they are available on such IP and they can connect to server or provide additional information to server. Normally instead of broadcast, multicast is used which is limited broadcast. All the clients and server will subscribe to the multicast group which is a special kind of IP address. When server send a message to this multicast address all the client, which are subscribers of this address will receive this message and can respond back. Here is a sample
Edit: you can also use boost lib to implement multicast: sender eg., receiver eg.

Receiving Multicast From Different Ports

Basically I have an application that creates say 5 multicast sockets on the same interface and within the same application, each socket binds to a different multicast IP address/port. When any one of those sockets sends a message, the other 4 sockets within the application end up reading that message. Is this normal behavior?
This is happening in Ubuntu 11.10 using boost.asio and gcc 4.6.
It's normal in some operating systems ;-) You can turn it off with setsockopt() and the IP_MULTICAST_LOOP option.
Sounds strange to me. If you are using UDP, then you should only receive messages associated with the port number of the UDP socket. Of course, if you using multicast at the IP level, then the port number would not matter.
It is quite true (as per EJP) that loopback will cause programs to receive their own messages if loopback isn't disabled. However, the UDP port numbers still apply. A multicast UDP message sent to port x, should not be received by a socket listening for port y.