Unicast response to multicast? - c++

This may be a silly question (but I'm new to multicast). I have a process that spawns two threads -- one for listening to a multicast IP (listener) and one for broadcasting to it (speaker). I'm planning on introducing many of these processes.
My question is, if a listener receives a multicast packet, can it send a unicast response to whichever process' speaker sent it without opening a new unicast-style socket?
EDIT: at the very least, I can pull the IP address of the speaker's multicast packet and connect to some unicast-style port that process may be listening on, right?

EDIT: at the very least, I can pull the IP address of the speaker's multicast packet and connect to some unicast-style port that process may be listening on, right?
Multicast packets (actually any IP packets) have source and destination IP, the only difference in multicast is that destination addresses are of groups and not computers , starting with 224.0.x.x.
The source is always the real IP of the sender (unless it's behind NAT, in this case it will be the gateway's IP address).
This means that you can extract the IP of the sender, and IF this sender has a server (==listening) socket, and all network configurations (Forwarding table & Firewall) allow access to that socket, you will be able to initiate a TCP Session with it...

Related

How can I send Broadcast message in c++ builder 6

What I want is to know how to bind two computers for my online game.
I made it using Server Socket and Client Socket and it works. But how can I do the same if it's unknown where this program is running. So I can't connect because I don't know who is the server. I was told that I can send broadcast message but now it's the third day of my endless attempts to do it...
I tried to write it like this (c++ builder 6):
ClientSocket->Socket->SendText("Message");
The address and host is 192.168.0.255;
And I run it twice in one computer at the same time but it does not work (because I don't know what to do then)).
Please, help me to find the server that I don't know beforehand.
I was told that I can send broadcast message
That is one way to do it, yes (it is not the only way). However, that only works if the client PC and server PC are connected to the same network.
The server app can open two listening sockets, one for TCP and one for UDP (IPv4 only) or Multicast (IPv4 or IPv6). IPv6 does not support UDP broadcasts, so you have to use Multicast instead.
The client app can then:
for UDP, send a message to the UDP port using the broadcast IPv4 address of the subnet that it is connected to. The message will be delivered to every device connected to that subnet. If the server PC is connected to the same subnet and the server app receives the broadcast message, it can send a reply back to the IPv4 address that sent the broadcast. When the client app receives the reply, it will know the IPv4 address that sent the reply.
for Multicast, subscribe to the server PC's Multicast group address. The server can periodically send its current IP address to the group, and any clients that are subscribed to the same group will receive it. When the client receives the message, it will know the IP address that sent the message.
Once the client has discovered the server's IP address, it can connect its TCP client socket to that IP address using the TCP port.
If the two PCs are not on the same network (ie, they are connecting over the Internet), then the above does not apply. The server will have to publish its current IP address somewhere that the client can find it, such as on a public website, or a Dynamic DNS service.
Of course, the simplest solution is to just ask the server admin for the server's current TCP IP/port, and then you can enter that into your client app's configuration as needed.
I tried to write it like this (c++ builder 6):
ClientSocket->Socket->SendText("Message");
TClientSocket uses TCP/IP. To send a subnet broadcast using UDP, you need to use UDP component instead. C++Builder 6 ships with FastNet, which has a TNMUDP component, as well as Indy, which has TIdUDPClient and TIdUDPServer components. Or, you can write your own UDP socket code using the WinSock API directly.
Indy also provides Multicast
The address and host is 192.168.0.255
That is the broadcast IP address for an IPv4 192.168.0.x subnet that has a 255.255.255.0 subnet mask. If that is your actual subnet configuration, and your client and server PCs are both connected to the 192.168.0.x subnet, then yes, you can send a UDP broadcast message to that IP address.
To obtain the subnet broadcast IP address, you can either:
calculate it manually. Use GetAdaptersInfo() or GetAdaptersAddresses() to get the local PC's current IPv4 address and subnet mask, then mask the bits of the IP address with the bits of the subnet mask using an AND operator, and then OR the result with the inverse bits of the network mask.
ask Windows. Create a socket and bind() it to the desired local network adapter. and then use WSAIoctl(SIO_GET_BROADCAST_ADDRESS) to query the broadcast IP address associated with that network.

Port and IP address usage in UDP communication

I have two clients and I want to connect them to daemon which is using UDP socket. It is using IP addr1 and Port#1 for communication. In each client, I create a socket with the same IP and port#1 that daemon is using. Is that okay to use same IP address and port# for both clients?
That depends on what you mean by "use."
It is correct for both clients to do connect() or sendto() using the IP and port the daemon is listening on.
It would not be ok for any of the clients to do bind() using the IP and port the daemon is listening on.

How to connect a server and a client that is behind router using QUdpSocket?

Assume that I have a server directly connected to internet and a client connected to a router. The client can send messages to server since it knows the server's IP address and port. But how does the server send message back to the client? It can get the client's external IP address and port but should it send message to that port? and how does the client listen to the message,which port should it listen to? assuming no port forwarding.
I assume the difficulty is that your client is behind a NAT firewall. If that's the case, then the answer is simple: you don't. That's the entire point of NAT.
But this also assumes that you're talking about the creation of a new socket from the server to the client. If the socket already exists, you just talk over it and the stateful NAT router keeps track of the things it needs to in order to get the message through.
If neither of these answers your question, you'll need to reformulate it.

Socket listening on an IP subnet in C / Unix

I'm trying to write a server-client socket program in C. The objective is for the server to listen on a specific port, but across a range of IP addresses belonging to the same IP subnet. This IP subnet is part of the 127.x.x.x range (not 127.0.0.1 of course).
Couple of points to note:
This is a stream-based socket, and not Datagram sockets.
This is not a broadcast address.
Implementation in C/C++ only on Unix/Linux platform
I do not want to open multiple sockets on the server for each IP address in the range. This is not scalable.
Any help would be ideally appreciated. Is this even feasible?
You can only bind to one address on a single socket. Why can't you bind to INADDR_ANY and simply reject any packets not bound for your target IPs? Alternatively, you could bind to an arbitrary port and use OS-level magic (e.g. iptables, bpf) to reroute packets destined for those IP/port combinations to your socket.
The socket API does not allow binding to a subnet -- you can bind to one IP or to any IP. You can listen for all inbound connections and reject those that don't apply. If you need to divvy connections out between processes on the same server, use a single listening socket, and transfer incoming connections to the worker processes.
You can use a firewall to prevent anyone from outside the desired subnet from connecting (that's at the o/s level). You can put the socket in promiscuous mode and accept all connections on a given interface. I don't know if you can do both (have a socket in promiscuous mode and run iptables on it). Essentially it's like building a packet sniffer that only listens on one port.

receiving datagrams sent by client over internet

I made two console app: Broadcasting listener and UDP writer (for practice only). Each run on different machine over the internet.
Broadcasting listener:
INADDR_ANY, port 5555
Udp writer:
Enabled Broadcasting (setsockopt, SO_BROADCAST)
Case:
The writer send some datagrams to listener server (ip: 113.169.123.138). Listener can receive those datagrams.
The writer broadcasting to 255.255.255.255. Listener can not receive anythings.
Question:
What i need to do to make case 2 work?
Your broadcasts are meant for your subnet and not the internet.
For example DHCP -- this application is meant to perform broadcasts to assign IP addresses to machines logically part of a particular subnet.
If you join the reader machines subnet via a VPN, then the reader machine will be able to receive your broadcast.