same application listening for packets from two different ip's - sockets

Can one application handle incoming UDP packets coming from two different ip's? If so, can those two connections use the same port number?

Yes, that's the point of a server in general: multiple clients can connect to the server on the given UDP port and they can all broadcast data on the same channel. The server doesn't need to have a separate socket connection for each client, instead it just broadcasts data via its socket connection to the same channel that the clients broadcast.
UDP is a little like sitting in a room where everybody yells at each other, while TCP is like talking on the phone with multiple people at the same time.

Related

UDP server sockets in multiple threads with SO_REUSEPORT

For my UDP application I want to spread the handling per session (4 tuple) over to different threads. But looks like if there are multiple server sockets (bind calls) for unicast packets kernel will deliver the packet only to one of the threads.
Is this the behavior always or are there any config knobs to enable per session routing of the incoming packets to different sockets ?
Pointer to the relevant functions in the kernel code that delivers the incoming packet to the socket will also be helpful.
Thanks.
But looks like if there are multiple server sockets (bind calls) for unicast packets kernel will deliver the packet only to one of the threads.
This is correct, the packet will only be delivered to one socket.
... enable per session routing of the incoming packets to different sockets ?
There are no sessions in UDP and thus no per sessions routing.
It is possible though to connect UDP sockets, i.e. call both bind and connect. In this case the packet will be delivered to the connected socket. If there are multiple connected sockets for the same source it will again be delivered to only one. And note that a connected socket will only receive packets for this connection, i.e. not from arbitrary sources like an unconnected socket.
Pointer to the relevant functions in the kernel code that delivers the incoming packet to the socket will also be helpful.
This behavior is not specific to Linux.

Socket broadcast basics

I am building an application that will deploy in effect on multiple "clients" with a common "server". Clearly I could communicate between each client and the server using a single read-write socket for each client-server link, or a read socket and a write socket per link if I really wanted to.
But what if there are (hopefully good) reasons that the server wants to read from any client, and broadcast back to all? If you have a connectionless protocol like UDP, can the server use only a single read-write socket, or must it use one for reading and one for writing? What about the clients? And does this change if you use a connection-based protocol like TCP?
If you have a connectionless protocol like UDP, can the server use only a single read-write socket, or must it use one for reading and one for writing? What about the clients? And does this change if you use a connection-based protocol like TCP?
A socket as an endpoint which has at least a local address and port in case of UDP and TCP. Only data received for this ip and port are delivered to the socket and all data send from this socket contain the local ip and port as the source. A socket can be connected, in which case also the destination IP and port is known. With TCP a socket needs to be connected, with UDP not.
This means:
You can use the same unconnected UDP socket to send data to multiple peers (destination is an argument for the sendto function). You cannot do this with TCP, i.e. you need a connected socket for each single peer.
You can receive data from multiple peers on an unconnected UDP socket. You cannot do this with TCP.
The special broadcast address can be used with UDP but not with TCP, since with TCP you need to have a connection between only two clients which is not the case with broadcast.
See also a related question with answer for more information: Bidirectional UDP Multicast
But what if there are (hopefully good) reasons that the server wants
to read from any client, and broadcast back to all?
Well, then you'd probably want to use a UDP socket (either instead of, or in addition to, some TCP sockets) :)
If you have a connectionless protocol like UDP, can the server use
only a single read-write socket, or must it use one for reading and
one for writing?
A single UDP socket is sufficient for both reading and writing (although some multithreaded designs might find it easier to use two separate sockets instead; either way will work).
What about the clients?
Clients can also use a single socket for both sending and receive UDP packets, if that's what you're asking.
And does this change if you use a connection-based protocol like TCP?
With TCP sockets you can also use a single socket for both sending and receiving. However you will need one TCP socket for each destination that you want to send or receive to/from. (Contrast this with UDP where a single UDP socket can be used in conjunction with sendto() or recvfrom() to communicate with multiple peers)
As per your requirement, you have two ways :
By using TCP connection only : Server reads message from client and for the broadcasting to all clients,server writes message to all client's TCP sockets(connected to clients) and clients read that message from TCP socket(connected to server).This method requires that client and server knows the IP addresses of each other
By using TCP connection for the client-server direct communication and UDP for broadcasting : In this method,client and server communicates (directly one to one) using TCP connection. For broadcasting the message, server can broadcast the message over the network using UDP socket and clients have UDP broadcast receiver for receiving the broadcast message.

Can a UDP multicast server send packets outside LAN?

I'm in the process of making a multiplayer game, where the players' movements are sent over the network and their positions are stored in the server. I've been told that UDP would be best since it doesn't rely on constant connection and it won't matter if the client misses a packet. The clients could be on any router, not necessarily within the server's LAN.
Is it possible to set up a server that the clients can connect to that will send all of them periodic updates of the positions of nearby objects/players?
I don't want to have to send packets to each individual client, and I heard multicasting can solve this problem, but every example I've seen only sends packets over a local network. Can I multicast past routers, and if so, how can I do that in Java? (And explain it to me like I have no idea what I'm doing, which is mostly true)
Ex.
Server has IP address 71.10.200.133
Client A has IP address 38.49.339.293
Client B has IP address 37.28.487.388
...
Client Z has IP address 43.38.382.949
Client A sends an update about the player's position to Server
Server sends update to B-Z without iterating a packet to each individual client. How do I accomplish this (if it's possible)?
Multicasts will traverse a router if and only if the router allows it. Unless you're in control of all the routers between you and your clients, the answer to your question is 'no'.
Multicast packets are broadcasts, thus they reach each node on that subnet. For you to send a multicast packet out on the web is not an effecient nor smart way of sending data.
For LAN based traffic:
Multicast is fine
But, for internet traffic I would suggest making a:
UDPClient
or
TCPClient
for internet based traffic and possibly multicast for LAN based (to mix things up a bit).
For internet traffic: Keep in mind, clients will need to initiate the connection first since most routers (household) have a firewall blocking all NEW outside-to-in traffic. So create a socket to listen over a designated port/ports for any incoming connections and from there on use which ever method of packet broadcasting/sending you like
You do also have the option of using Multicast proxies or Layer 2 VPNs if you have the capabilities. L2TP, https://en.wikipedia.org/wiki/Layer_2_Tunneling_Protocol
A layer 2 VPN would relay unicast and multicast packets.
That would basically allow you to control the routers as EJP suggested above.
This questions also 3 year old so you've probably already figured a way to do it by now.

Broadcasting ip:port by socket server

I'm trying to find a way for client to know socket server ip:port, without explicitly defining it. Generally I have a socket server running on portable device that's connect to network over DHCP (via WiFi), and ideally clients should be able to find it automaticaly.
So I guess a question is whether socket server can somehow broadcast it's address over local network? I think UPnP can do this, but I'd rather not get into it.
I'm quite sure that this question was asked on Stack lot's of times, but I could find proper keywords to search for it.
One method of doing this is via UDP broadcast packets. See beej's guide if you're using BSD sockets. And here is Microsoft's version of the same.
Assuming all the clients of the application are on the same side of a router then a broadcast address of 255.255.255.255 (or ff02::1 for IPv6) should be more than adequate.
Multicast is another option, but if this is a LAN-only thing I don't think that's necessary.
Suggestion
Pick a UDP port number (say for the sake of an example we pick 1667). The client should listen to UDP messages on 255.255.255.255:1667 (or whatever the equivalent is. e.g.: IPEndPoint(IPAddress.Any, 1667)). The server should broadcast messages on the same address.
Format Suggestion
UDP Packet: First four bytes as a magic number, next four bytes an IPv4 address (and you might want to add other things like a server name).
The magic number is just in case there is a collision with another application using the same port. Check both the length of the packet and the magic number.
Server would broadcast the packet at something like 30 second time intervals. (Alternatively you could have the server send a response only when a client sends a request via broadcast.)
Some options are:
DNS-SD (which seems to translate to "Apple Bonjour"): it has libraries on macOS, but it needs to install the Bonjour service on Windows. I don't know the Linux situation for this. So, it's multi-platform but you need external libraries.
UDP broadcast or multicast
Some other fancy things like Ethernet broadcast, raw sockets, ...
For your case (clients on a WiFi network), a UDP broadcast packet would suffice, it's multi-platform, and not too difficult to implement from the ground up.
Choosing this option, the two main algorithms are:
The server(s) send an "announce" broadcast packet, with clients listening to the broadcast address. Once clients receive the "announce" packet, they know about the server address. Now they can send UDP packets to the server (which will discover their addresses for sending a reply), or connect using TCP.
The client(s) send a "discover" broadcast packet, with the server(s) listening to the broadcast address. Once the server(s) receive the "discover" packet, it can reply directly to it with an "announce" UDP packet.
One or the other could be better for your application, it depends.
Please consider these arguments:
Servers usually listen to requests and send replies
A server that sends regular "announce" broadcast packets over a WiFi network, for a client that may arrive or not, wastes the network bandwidth, while a client knows exactly when it needs to poll for available servers, and stop once it's done.
As a mix of the two options, a server could send a "gratuitous announce" broadcast packet once it comes up, and then it can listen for "discover" broadcast requests from clients, replying directly to one of them using a regular UDP packet.
From here, the client can proceed as needed: send direct requests with UDP to the server, connect to a TCP address:port provided in the "announce" packet, ...
(this is the scheme I used in an application I am working on)

UDP for multiplayer game

I have no experience with sockets nor multiplayer programming.
I need to code a multiplayer mode for a game I made in c++. It's a puzzle game but the game mode will not be turn-based, it's more like cooperative.
I decided to use UDP, so I've read some tutorials, and all the samples I find decribes how to create a client that sends data and a server that receives it.
My game will be played by two players, and both will send and receive data to/from the other.
Do I need to code a client and a server?
Should I use the same socket to send and receive?
Should I send and receive data in the same port?
Thanks, I'm kind of lost.
Read how the masters did it:
http://www.bluesnews.com/abrash/chap70.shtml
Read the code:
git clone git://quake.git.sourceforge.net/gitroot/quake/quake
Open one UDP socket and use sendto and recvfrom. The following file contains the functions for the network client.
quake/libs/net/nc/net_udp.c
UDP_OpenSocket calls socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)
NET_SendPacket calls sendto
NET_GetPacket calls recvfrom
Do I need to code a client and a server?
It depends. For a two player game, with both computers on the same LAN, or both on the open Internet, you could simply have the two computers send packets to each other directly.
On the other hand, if you want your game to work across the Internet, when one or both players are behind a NAT and/or firewall, then you have the problem that the NAT and/or firewall will probably filter out the other player's incoming UDP packets, unless the local player goes to the trouble of setting up port-forwarding in their firewall... something that many users are not willing (or able) to do. In that case, you might be better off running a public server that both clients can connect to, which forwards data from one client to another. (You might also consider using TCP instead of UDP in that case, at least as a fallback, since TCP streams are in general likely to have fewer issues with firewalls than UDP packets)
Should I use the same socket to send and receive?
Should I send and receive data in the same port?
You don't have to, but you might as well -- there's no downside to using just a single socket and a single port, and it will simplify your code a bit.
Note that this answer is all about using UDP sockets. If you change your mind to use TCP sockets, it will almost all be irrelevant.
Do I need to code a client and a server?
Since you've chosen to to use UDP (a fair choice if your data isn't really important and benefits more from lower latency than reliable communication), you don't have much of a choice here: a "server" is a piece of code for receiving packets from the network, and your "client" is for sending packets into the network. UDP doesn't provide any mechanism for the server to communicate to the client (unlike TCP which establishes a 2 way socket). In this case, if you want to have two way communication between your two hosts, they'll each need server and client code.
Now, you could choose to use UDP broadcasts, where both clients listen and send on the broadcast address (usually 192.168.1.255 for home networks, but it can be anything and is configurable). This is slightly more complex to code for, but it would eliminate the need for client/server configuration and may be seen as more plug 'n play for your users. However, note that this will not work over the Internet.
Alternatively, you can create a hybrid method where hosts are discovered by broadcasting and listening for broadcasts, but then once the hosts are chosen you use host to host unicast sockets. You could provide fallback to manually specify network settings (remote host/port for each) so that it can work over the Internet.
Finally, you could provide a true "server" role that all clients connect to. The server would then know which clients connected to it and would in turn try to connect back to them. This is a server at a higher level, not at the socket level. Both hosts still need to have packet sending (client) and receiving (server) code.
Should I use the same socket to send and receive?
Well, since you're using UDP, you don't really have a choice. UDP doesn't establish any kind of persistent connection that they can communicate back and forth over. See the above point for more details.
Should I send and receive data in the same port?
In light of the above question, your question may be better phrased "should each host listen on the same port?". I think that would certainly make your coding easier, but it doesn't have to. If you don't and you opt for the 3rd option of the first point, you'll need a "connect back to me on this port" datafield in the "client's" first message to the server.