I am working on a C++ server/.NET client applications couple in which my server (which runs the c++ on linux) broadcasts a message to show it's alive to the whole network and my .NET program listens for packets and parses to get the uptime of the server.
As I have read, to send a regular UDP broadcast to the broadcast address, I simply have to send a packet to 192.168.0.255 (in my case 192.168.2.255) or 255.255.255.255. Is this right? Can I use the same port address? Are there any other necessities?
I understand the fact that if my .NET program listens on that particular address it is possible to receive packets from other applications than my C++ server program. Is there any method of "signing" the packet on the C++ server-side in order for my .NET program to read the header of the packet and see that it is (almost) the one I am looking for?
Regardless of the language you are using, here is my answer:
Regarding the broadcast IP addresses, both addresses are broadcast addresses but the limited broadcast address (which is 255.255.255.255) won't be forwarded by routers. It is better to use the subnet-directed broadcast address (192.168.2.255).
In order to send/receive a broadcast address, you need to define your broadcast address (broadcast IP address and port number). For example: 192.168.2.255 and port number 3000. The client applications (the senders) MUST enable SO_BROADCAST socket option as follows:
int enabled = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &enabled, sizeof(enabled));
where sockfd is the socket descriptor.
The server application will listen on a specific port number (port 3000). Normally, the server will respond to each request using unicast message.
There will be no conflict as long as no application is listening on the same port number. Your server will not run if another application is listening on the same port unless you enabled SO_REUSEADDRESS socket option. However, if there is a conflict, then your signiture is depending on your protocol (message format). So, check the message format and reject the message if it does not follow the message format defined by your application protocol.
For client applications, the received packet is unicast (unless you have another design). So, no conflict at this side.
You also have to enable the SO_BROADCAST socket option in C++ to send broadcast traffic, or you'll get a permission denied error:
int broadcastPermission = 1;
setsockopt(socketDescriptor, SOL_SOCKET, SO_BROADCAST, (void*)&broadcastPermission, sizeof(broadcastPermission))
If your .NET program listens for broadcast traffic, it will receive any and all broadcast traffic on the network sent on that port, including traffic not sent by your server. You could put a "marker" in the payload of the broadcast messages sent by your server. This way, your .NET program could distinguish which ones it cares about.
Beyond that, I would recommend using multicast instead of broadcast. Broadcast traffic is usually restricted to hosts on the same subnet. In layman's terms, if you have a router in your network, a host on side A of the router will not see broadcast traffic sent by a host on side B (and vice versa) because the router "blocks" it. Routers will almost always forward multicast traffic if a host has joined the multicast group.
Related
I am trying to send UDP Packets to a public server from a client in symmetric nat. i am able to send packets to the server However i want the server to send packets to the client under symmetric cone nat. How do i solve this? Please help me.
Make the server send packets to the client's external IP+Port which the server detects on the arrival of first packet from client.
Basically, the router allows any outgoing UDP traffic from the devices connected to it and blocks all incoming UDP traffic. But it maintains a table of source and destination IP+port whenever a UDP packet is sent out. It allows replies from devices external to the router, provided the router must have an entry of external device IP+port.
So, you just need to use this mapping in the table now.
Just make your server detect the client's external IP+port from the packet it receives from the client and then let the server send back packets to the client on that external IP+port.
This will punch a hole in the router's firewall i.e., the router firewall will now allow the incoming UDP packets as it already contains an entry in it's table. This process is called HOLE PUNCHING.
You can understand all this NAT traversal process in the various RFC's published.
I am trying to write code on OSX in c (can use objective-c too if easier) to determine if multicast is enabled on the current machine (router the machine is connected to). To do this I am trying the following steps:
Open a port and send data over multicast.
Listen for responses on all active adapters.
Filter out the 'loopback' adapter.
If no replies, multicast is likely disabled.
Being new to network programming, I don't understand how I would get a response from any active adapters by sending out random data, unless I had software installed on the machines that were listening. Is there a certain multicast IP reserved that will always elicit a response, or is there a better way to go about doing this?
To determine if a machine has IP multicast addresses active (which is what I think you mean by "multicast is enabled"), look at the routing table and see if you find one or more IP v4 addresses in the range 224.0.0.0 to 239.255.255.255.
Multicast is implemented by DHCP, which is not your local computer. DHCP allocates addresses whihc correspond to multiple clients that are connected to that DHCP server. When you craft a multicast message, you send it to this DHCP server, which then takes the packet, finds the clients who are mapped to that multicast address, and then send it in a special packet that routers automatically duplicate (so if you have 2 people part of the group connected to 1 router, and that router is connected to another router (called router 2), router 2 won't send two packets, it will send one, and then router 1 will send two copies to its clients. The purpose of this is to speed up delievery time and not send duplicate data). As far as the clients, the clients aren't "set up" to allow multicast, but rather the router sets them up, and the rest is transparent to the client. The way you would have to find out if a client is connected to a multicast group, is to see if the DHCP server has created a multicast group, and then find the computer names from the IP addresses that are mapped to the multicast group.
By listening to all active adapters, you're not going to get anything but packets, which aren't going to tell you if its part of a multicast network, since they're going to look like every other packet (since the router will change the multicast address to YOUR ip address before you even see the packet). That's the beauty of multicast.
I have a program that broadcast UDP to my local network, and one host device would read this message and function upon it perfectly.
Now I want to do this job remotely, knowing that where is the reciever host I have a public static IP provided by the ISP, and for example I'm out side this network and I want to broadcast this UDP traffic to it through the Internet, is there any possible routing configuration that would allow this trafic to reach the local network and just explode there ?
And if not. Is there any other way that can make this trafic, instead of broadcasting to be directed to this receiver host directly ? That would require then only some port forwarding in my static ip router.
By RFC, broadcasts cannot be forwarded by routers. Plus, several ISP will filter out such packets anyway. Broadcasts are limited to the local subnet only.
I suggest you look into multicast instead.
I want to create a Console Application in VB that broadcasts to all IPs on Local Area Network his own Ip.
So a Timer that broadcasts the IP of the server every second. Every client that connects, receives the IP of the Server.
Then, a client logs in to the Application and sends 2 strings to the Servers IP:
Username
Password
The server checks the validity of the 2 strings, and either allows or restricts access to the Server.
How should I proceed?
I have found TcpClient and TcpListener, but I am unable to broadcast an IP to 255.255.255.255...
Mainly, what I want to achieve, is broadcast (255.255.255.255) my Local Ip (192.168.1.1), so I would broadcast the String "192.168.1.1"
You should take a look at the UDP classes instead of the TCP classes. UDP will allow you to broadcast small messages on your LAN. One the IP address is received, then you can use TCP to connect to the server.
I'm sniffing between two devices which communicate in a duplex fashion via udp. I'm using wireshark to sniff. The config file for the first device (a piece of hardware under test) states that the client port is 54718 and the server is 54717. In the config file for the second device (a simulator written years ago), only one port is specified. That of 54718.
The two devices communicate without any problems.
But how does the second device manage to connect and send to 54717 when it has no knowledge of it?
In wireshark I can see that the first device is sending to the second device such that the source port is 54717 and the destination is 54718. I can also see that the second device is sending to the first device such that the source port is 54718 and the destination is 54717.
The first device sends first and the protocol is described as that of UDP in Wireshark. The simulator replies, also via UDP. Subsequent exchanges are described as being STUN ChannelData TURN Messages. I've no knowledge of this protocol but maybe it explains why I don't see 54717 in the simulators config file.
Thanks for your help,
Barry
First, in UDP communication, there is no "connect" action. UDP is not connection-oriented.
Second, the second device will get the peer address and port from recvfrom() api call.
In all probability, the first device's use of the terminology "client port" and "server port" do not refer to two different ports within the client device. Instead, the "client port" refers to the port to be used as the point of origin within the first device, and the "server port" refers to the remote destination port on the far device, to which the first device's outgoing traffic will be sent.
The second device, on the other hand, is probably fundamentally a "listening" device. It only knows the UDP port it needs to listen on, and waits for any queries destined to that port to arrive from anywhere.
So, I will refer to the "first device" as the client, and the "second device" as the server.
Each datagram sent from the client to the server contains two sets of address information:
1) The destination IP address and port, and
2) The return IP address and port.
The server can use recvfrom() to extract the complete return address (including port number) from each incoming request.
This way, we really only need one port number to be predfined and agreed upon by both the server and the client ahead of time: The server's port number.
The client could conceivably choose to use any random port number as its origin port (but by convention it would likely choose to avoid any of the well-known reserved ports to avoid potential interoperability problems), and the server could dynamically read the return address information from each incoming request and send its responses to the correct destination dynamically.
But how does the second device manage to connect and send to 54717 when it has no knowledge of it?
UDP is connectionless, and your program likely gets the 54717 as a default fallback value if nothing else is specified (e.g. in a config file).