Why does the UDP client port change on the UDP server - c++

I've been following a simple UDP server/client tutorial found here, and I have a quick question about which port the client is connecting to the server.
From just viewing the code, it seems quite obvious that the server and client are connecting via port 8888:
Client.cpp
#define SERVER "127.0.0.1" //ip address of udp server
#define BUFLEN 512 //Max length of buffer
#define PORT 8888 //The port on which to listen for incoming data
Server.cpp
#define BUFLEN 512 //Max length of buffer
#define PORT 8888 //The port on which to listen for incoming data
However, when I actually run the server and the client, the server says the client connected port is always different:
First run (Server Log):
Note how the port changes from 8888
Second run (Server Log)
Note how the port changes again
Why would the connected ports change from 8888?

The comment in the client is incorrect. They just copied that line from the server, but they should have changed it to:
#define PORT 8888 //The port to send outgoing data to
The client and server both put the port in a sockaddr_in structure. The server uses this structure in its call to bind(), which sets the listening port. The client uses it in the call to sendto(), so it sets the destination port.
Since the client never calls bind() to set a specific local port, the source port is selected arbitrarily from the ephemeral port range. Each socket gets a different port to distinguish them.
If a fixed port were used as the client's local port, you wouldn't be able to have multiple clients on the same machine, since there would be no way to know which client should receive an incoming packet from the server. So fixed ports are typically used for servers, which random ports are used on the client.

When sending a UDP packet from one computer to another, there are two ports involved: the port that the receiving computer's UDP socket is bound to and is receiving on (8888 in your case), and the port that the sending computer is sending from. The port that you see changing is the port that the sending computer is using to send UDP packets from. Since the sending computer never explicitly chooses a UDP port to bind to (i.e. it never calls bind() with a non-zero argument), the sending computer's TCP stack simply picks a currently-available UDP port to implicitly bind the sending UDP socket to, and this port may be different each time the sending program is run.

8888 is the server port. The 5 digit port you see on logs are client ports created to eventually get data back from the server. This is an automatic and totally fine mechanism.

Related

My friend and I are receiving packets from a server in UDP, I am able to receive them but he can't

My friend and I are writing a game in sfml. We wrote both the client and the server in C++. The library we used to handle the networking is SFML. The clients send block update packets to the server and the server sends them to all connected players. This works fine, both my friend and I are able to receive the TCP packets. The problem is with the UDP player position packets. The server receives a UDP packet containing the players x y z (position coordinates) and pitch and yaw(direction the player is looking). Then it sends that information to all other connected clients.(This happens 10 times per second) We put a simple printf() statement to detect whether my friend is even receiving the udp packets but it turns out he was not. And I am obviously receiving the UDP packets since it I am able to see his position.
We thought this was because the server is sending UDP packets to the clients' router's IP but the packet does not contain the local ip of the computer the packet is meant for. Later, we learned that when the server sends a packet to the router, the packet gets sent containing a public ip address and a public port, the router then maps that port to a local ip address and a local port. However this is called port forwarding and requires the routers to be configured.
We just want to know why isn't this a problem with TCP connections?
Why am I able to receive the UDP packets without port forwarding?
Is port forwarding necessary for UDP communication?
We just want to know why isn't this a problem with TCP connections?
Because a connection is bidirectional.
Why am I able to receive the UDP packets without port forwarding?
There could be a lot of possibilities and there's no way we can know without looking much more closely. Here are a few possibilities:
You aren't behind a router that's doing NAT.
The router that does NAT for you isn't between your client and the server.
Your client sent a UDP datagram to the server and your router recognizes the response UDP datagram as a reply to that, creating the effect of having a "UDP connection".
Your client uses UPnP and your router supports UPnP to get port forwarding without special effort.
The server sets the source and destination UDP ports incorrectly and, by luck, it still works in your case. For example, the source and destination ports might happen to be the same or your router's NAT is especially permissive.
The server sets its source IP address incorrectly and this just happens to work in your case either because your router's NAT is more permissive or because the IP address you send to and the IP address the server sends from happen to be the same in your case.
You send a UDP datagram to the server and your friend didn't, thus your datagrams are seen as replies and your friend's aren't.
You can narrow things down if you can dump packets at the server. Seeing a UDP datagram from your friend as seen by the server followed by a UDP datagram from the server to your friend would help narrow things down a lot.
Is port forwarding necessary for UDP communication?
Generally no. If the client sends the first UDP datagram and the server correctly swaps the source and destination ports and the source and destination IP addresses, the UDP reply datagram will usually work.
The client must send UDP to the server first. The server must ensure that the UDP datagram is seen as a reply. That means the server looks at the UDP datagrams it gets from the client and ensures that it responds from the port the client sent UDP to and to the port the client sent UDP from. Similarly, it must send to the IP address the client sent from and send from the IP address the client send to.
Generally, servers offer TCP fallback or some other form of NAT penetration in case things don't "just work".

Can a tcp client use the same port to a different Server?

I want to write a tcp server and client application, which has several different connections to each other where the client uses the same port number.
So far I understand it, the server has a listener port and when the client calls it, then I get a new socket for this new connection on the server side, when I call
accept();
Right? So on Server side I can identify my connection with this new socket and send data through it.
Now my understanding problem with the client side. There I get my socket when I call
socket(AF_INET, SOCK_STREAM, 0)
so I have only one socket. In the
connect()
I can specify remote adress and so on. So when I understand it correctly I can use one socket to make several connects to different adresses/port pairs to create different connections. Right?
But how can I now see in the Client from which logical connection I receive my data or how can I send it when 2 logical connections use the same local port at the client? On serverside I have 2 sockets when I have 2 accept called but what about the client side? For send and receive I have only one socket handle?
Or do I have to call socket() for each logical connection on the client?
I can specify remote adress and so on. So when I understand it correctly I can use one socket to make several connects to different adresses/port pairs to create different connections. Right?
No. A socket is the combination of IP address plus port number.
Or do I have to call socket() for each logical connection on the client?
Yes.
It seems to me your confusion arises because you think for example that a certain port is used for SMTP connections and a certain port is used for HTTP connections.
Well, that port alone is NOT defining for you a socket to the server. The IP address of the server is changing.
As an example, consider the following scenario:
You want to connection to Stackoverflow:
Your PC – IP1+port 50500 ——– Stackoverflow IP2 + port 80 (standard http port)
That is the combination IP1+50500 = the socket on the client computer and IP2 + port 80 = destination socket on the Stackoverflow server.
Now you want to connect to gnu.org:
your PC – IP1+port 50501 ——–gnu.org IP3 +port 80 (standard http port)
The combination IP1+50501 = the socket on the client computer and IP3 + port 80 = destination socket on the gnu.org server.
Better check out Beej's Network Programming to learn more. It is a must-read for anyone working with sockets.
So when I understand it correctly I can use one socket to make several connects to different adresses/port pairs to create different connections. Right?
No. A TCP socket can only be used once. When its connection has finished, or even if connect() just fails to make a connection, you must close the socket and create a new one if you want to make a new connection.
But how can I now see in the Client from which logical connection I receive my data or how can I send it when 2 logical connections use the same local port at the client?
Every TCP connection will have its own unique socket allocated for it. It is your responsibility to keep track of them.
On serverside I have 2 sockets when I have 2 accept called but what about the client side?
The exact same thing happens on the client side, too. You need to create and connect a separate socket for every TCP connection you make. So, you will have a new pair of socket()/connect() calls for every connection.
For send and receive I have only one socket handle?
No, you will have a separate socket for each connection, just like on the server side.
Or do I have to call socket() for each logical connection on the client?
Yes, and connect(), too.
I will not talk about a specific programming language rather I will give a general answer that is applicable for all:
In networking what you care about is the socket (IP+Port) this should be unique whether it is server/client socket or UDP/TCP socket.
For server sockets you must assign a port. For client sockets usually you do not specifically assign a port but it will be assigned by the operating system automatically. However, you can still assign a port to a client socket manually (e.g. in case some port numbers are blocked by the firewall)
In the server process:
you can get the server socket info and the connected client socket info
In the client process:
you can get the client socket info and the server (you want to connect to) socket info (of course you should know the server socket info previously otherwise how will you connect to it).
You can send/receive from/to client sockets. After the server gets the connected client socket it can send/receive through it. Same for the client side it can send/receive through its socket.
The "socket" abstraction is an unfortunate relic of past network stack design. It mixes two different sorts of objects.
A listening socket on the server has a port, and potentially an IP address of the local interface. However, this can also be 0.0.0.0 when listening on all interfaces.
A connected socket is associated with a TCP connection, and therefore has 4 parameters: {local IP, local port, remote IP, remote port}.
Now on the client side, you typically don't care about local IP or local port, so these are locally assigned on connect. And yes, these local parameters can in fact be reused for multiple connections. Only the 4-tuple of {local IP, local port, remote IP, remote port} needs to be unique. The OS will map that unique tuple to your SOCKET.
But since you need a new 4-tuple for every connection, it also follows you need a new SOCKET on both sides, for every connection, on both client and server.

Internet socket programming in c++ explanation needed

I have two computers, and I have created a network between them, One is server (Windows Server OS) and the client (Windows 10). Both computer also has connection to internet through wifi. To connect two Systems I am using Ethernet Cable
I like to know if I create a program for client in c++ that send packets using internet socket. Should I also create a listener on server too. And should I use port 80 to send packets and same port on server to listen to arriving packets?
Assuming you decide to use TCP, then:
Should I also create a listener on server too?
If you are using a connection-oriented protocol (such as TCP) then you must have one end listening, because otherwise you have no way to create the TCP connection.
And should I use port 80 to send packets and same port on server to listen to arriving packets?
You should use whatever port number you want, as long as something else isn't using it. The actual number doesn't matter as long as the server and client agree.
Valid port numbers are in the range 1 to 65535.

C++ - Assigning port to UDP client using two machines

I'm setting up a basic UDP server/client application using winsock on two separate machines on the same LAN using a switch. I need to send data down a specific port from the client to the server.
How I've done it so far is server is two sockets (one for sending, one for receiving) and binded the receive port to 7777. Client also has to sockets (one for sending, one for receving) sends a message to port 7777.
Now on the recvfrom() function, I get the senders port to be some arbitrary number 35708. However I want the senders port to be say 8000.
My question is, can I specify which port the message is sent from?
If you use bind() before sendto(), you can choose to set the port, or let the network stack determine the port.
struct sockaddr_in myaddr;
...
myaddr.sin_port = htons(PORT); /* where PORT is defined elsewhere */
or
myaddr.sin_port = htons(0); /* if zero, let the system determine the port */
BTW, I don't know if this matches your use case, but you don't need to setup two sockets for bi-directional communication. See, for example: http://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html

Running client and server on same machine

I have both a client and server application using UDP port 25565.
In order to run these on the same machine, because only one application may bind itself to port 25565, does this mean that it is necessary for me to use two separate ports for transmitting data between the applications?
What I have in mind is the following -
Client -> 25565 -> Server
Client <- 25566 <- Server
Is this the only solution or is there another way of handling this?
Your server application open a port and wait for client to connect.
Client need to know this port in advance so it can establish a connection to the desired service.
Client can use any available ports to initiate this connection (better to use ports > 1000).
The server sees in the incomming packet wich port the client is using, so it will send anwser to it. No need to specify it in your design.
After handshake the TCP/IP connection is then identified by these 4 values : server IP, server port, client IP, client port.
No other connection could have the same four values.
To answer your question. A TCP/IP connection is bi-directional, once established, the server can send data to the client and the other way around.
I would draw the scheme like this :
SERVER port 25565 <-> CLIENT port 25566 (or any other port)
Well, no. Only the server needs to listen on the port 25565 - the client will just connect to that port. There is no reason to specify which client the port should 'use' to connect to that port. Also, once the server has accepted the connection, the port can listen for other requests.
The whole point of separate UDP ports is to eliminate conflicts among applications listening to incoming packets. Changing one of these ports is probably the best solution.
However, if you really want both programs to listen on the same port you will need to use virtual network interfaces such as TUN/TAP (there is a Windows port). Then both applications will bind to the port with tha same number but on the different network interfaces.