1
votes

I'm currently implementing a UDP server browser feature, so a player can find servers of a game via a php page (IP & port) and then request game-data from this address. This game-data includes stuff like amount of players/game mode but also a "real" port, the game itself is based on TCP.

Example: Game on 1.1.1.1:1000 is registered on that php page

Now I want my server browser to send a UDP packet to this address and port and then listen for a response in order to obtain this game-data.

That's not a problem, at least not in a LAN without firewall restrictions.

I'm just curious if that will also work through the internet, let's say:

A server is running on 1.1.1.1:1000 (TCP for game AND UDP for game-data) behind a router. This server has its ports forwarded correctly, so clients can connect directly by IP and the game-data requests can be received and answered.

A client with IP 2.2.2.2 found this server on the server browser and wants to get the game-data. He's also behind a router, but hasn't got any ports forwarded.

Now in TCP this would be easy: A ServerSocket can accept incoming connections and answer them, the Socket for the client can receive the answers because the client himself made a request to the server, right?

Is this also the case for UDP? Like, the client sends a packet to 1.1.1.1:1000 via UDP. By default new DatagramSocket() binds to "some" available UDP port, let's say 2000 in this case. Now I can simply use socket.getLocalPort() and obtain this port, construct the request packet and put the client's port in there. After sending, the client uses this DatagramSocket object to listen for a response.

The server receives this request packet and has the client's local port number now, so it sends an answer packet containing the game-data to this port. (2000)

Is the client able to receive this packet? I'd say yes, because the client used this UDP port to send a packet to the IP it receives an answer from, so the firewall of the client should let "answers" to that port through.

And: Does the DatagramPacket.getPort() for a received packet contain the used UDP port on the sender's side? Example: Packet sent from port 2000 is received on port 1000 -> does getPort() return 1000 or 2000 ?

Thanks for answers :)

2

2 Answers

0
votes

There is no difference between TCP and UDP here. In both cases (client connecting to server, router doing port forwarding to server) there is NAT: Network Address Translation.

If we take the case of a client and server behind nat:

  • client sends a packet: srcip1, srcport1 -> dstip1, dstport1;
  • client's nat router translates: srcip2, srcport2 -> dstip1, dstport1;
  • server's nat router translates: srcip2, srcport2 -> dstip2, dstport2;
  • server receives packet.

The reverse happens when the server sends a packet back. But the principles are the same. And again, TCP, UDP, no difference here.

The only difference is how "hard" it is for routers to keep track of these address/port mappings. It is easier for TCP than for UDP (since TCP is session-oriented). But note that this must also be done for ICMP (which is necessary for ping, but also network unreachable messages and others; ping is echo-request out, echo-reply in).

(as a side note, maybe this belongs to serverfault?)

0
votes

Generally yes. A NAT will generally allow incoming responses to a UDP source-destination pair it has just seen an outgoing packet for. Timeouts vary, however.