The labs on this site need JavaScript to run. The same content is written out below.
Learn › Networking › Transport layer
Sockets and ports
Of the several programs on one computer, which one receives this data?
An IP address leads only to one computer. Which of the programs running on that computer receives the data is decided by the port number. A program creates a socket and binds it to a port number, and the operating system passes data that arrives for that port to that socket. This lab shows which program a connection reaches, depending on the ports the servers listen on and the port the client connects to.
Checked against real execution · The 27 combinations were run on 127.0.0.1 with the net module of Node.js 24 and checked against the results
Concepts in this lab
- Port
- A port is a number from 0 to 65535 that tells apart which of the several programs running on one computer should receive the data. If an IP address points to the computer, a port points to the program inside that computer, so the place to connect to is written as "IP address:port". A server program waits for connections on a port it has chosen, and some numbers are widely agreed upon, such as 80 (HTTP) and 443 (HTTPS) for web servers. Normally only one program can wait for connections on a port, so starting a server on a port that is already in use causes an "address already in use" error. The ports of TCP and the ports of UDP are managed separately, so the same number in each is a different thing.
- Socket
- A socket is the endpoint of communication that a program uses to send and receive data over a network, and the operating system creates it and hands it to the program. The program only writes to and reads from the socket, and the operating system does the actual work of splitting up, sending, and receiving the data. One TCP connection consists of a pair of sockets, one at each end, and the operating system tells connections apart by four values: the source IP address, the source port, the destination IP address, and the destination port. This is why a server can receive connections from several clients at once on a single port, with a separate socket created for each connection. If you do not close a socket after using it, the resources of the operating system stay tied up.
- Ephemeral port
- An ephemeral port is the source port number that the operating system chooses automatically when a client connects to a server. The client code writes only the port of the other side (the server), and the operating system lends a free number for its own side. When the connection ends, the number is given back and can be used again for another connection. The range from which numbers are picked depends on the operating system and its settings, so you must not assume that a particular number will come up. If a very large number of new connections are made in a short time, there may be no numbers left to lend, and a new connection can fail.
- TCP and UDP
- The two main ways of transporting data on the internet. TCP establishes a connection before communication, guarantees that data arrives complete and in order, and sends data again if there is a problem. UDP sends data without a connection and does not guarantee arrival or order, but in return it is lightweight and fast. HTTP/1.1, HTTP/2, and database connections use TCP, and real-time video and voice and DNS mainly use UDP.
Try these
- Default settings — Two servers cannot share one port, but three clients can connect to one port together.
- Choosing the program by port — Same computer, but sending to port 9001 reaches Server B.
- A port with no server listening — Even though the computer is on, the connection is refused.
- Port 9001 after Server B failed to start — B did not get port 9000, and nobody is on port 9001.
- One server, one client — Start with the simplest case.
Running with the default settings
- serverA.listen(9000): Server A creates a socket, binds it to port 9000, and registers with the operating system: "Give the connections that arrive on port 9000 to this socket." Port 9000 was free, so this succeeds. Server A now waits for connections.
- serverB.listen(9000): Server B also tries to register port 9000. Server A is already using it, so the operating system refuses, and Server B receives an EADDRINUSE (address already in use) error. Only one program can receive the connections that arrive on a port, because otherwise the operating system could not decide whom to give them to.
- Client 1 calls net.connect(9000): The code gives only the destination port. The operating system picks one of the free numbers (here 50001) as the source port. Server A is listening on port 9000, so the connection is established.
- Client 2 calls net.connect(9000): This time the operating system picks 50002 as the source port. Server A is listening, so the connection is established. The destination port is the same 9000 as in the earlier connection, and only the source port differs. The operating system treats connections as different if even one of the four values (source IP, source port, destination IP, destination port) differs.
- Client 3 calls net.connect(9000): This time the operating system picks 50003 as the source port. Server A is listening, so the connection is established. The destination port is the same 9000 as in the earlier connection, and only the source port differs. The earlier two connections are not closed and stay open.
- socket.write: Each of the 3 clients sends its data. All of it goes to port 9000, but the operating system looks at the source port to tell which connection the data belongs to, and passes it to Server A separately for each connection, because each connection has its own socket.
Result of this run
- Starting a server on a port that is already in use fails with EADDRINUSE. If you meet a "port already in use" error during development, most often the server you started earlier is still alive. End that program or use another port.
- Several clients can connect to one server port at the same time. Even when connections increase, the server side has only one port, 9000, and connections are told apart by the set of four values (source IP, source port, destination IP, destination port). A web server receiving many users on the single port 443 works on the same principle.
Code
// Node.js (net module). Both the servers and the clients run on this computer (127.0.0.1)
const net = require('net');
const serverA = net.createServer(conn => conn.on('data', d => conn.write('A')));
serverA.listen(9000, '127.0.0.1'); // start listening on port 9000
const serverB = net.createServer(conn => conn.on('data', d => conn.write('B')));
serverB.on('error', e => console.log(e.code)); // if it fails, the error name is printed
serverB.listen(9000, '127.0.0.1'); // the port that Server A already uses
for (let i = 1; i <= 3; i++) {
const socket = net.connect(9000, '127.0.0.1'); // write only the destination port. The source port is not written
socket.on('connect', () => {
console.log(socket.localPort); // the source port chosen by the operating system
socket.write('c' + i);
});
socket.on('data', d => console.log(d.toString())); // which server received it
socket.on('error', e => console.log(e.code));
}
Assumptions of this model
The 27 combinations were actually run with the net module on 127.0.0.1 of the PC used to write this lab (Windows, Node.js 24) and checked against the results. What was checked: the result of the listen call of Server B (success or EADDRINUSE), the number of successful and refused client connections (ECONNREFUSED), the server that received the data, the number of connections the server saw, whether the ports of the server-side sockets were all the same as the one listening port, and whether the client-side ports were different from each other. In the runs, three ports that were free at the time were used instead of 9000, 9001, and 9002, and because the client-side port numbers (such as 50001 on the screen) change on every run, only the fact that they are "different from each other" was used as a result. The range from which an operating system picks ephemeral ports depends on the operating system and its settings (the range that IANA recommends is 49152 to 65535, Section 6 of RFC 6335). That a connection is identified by the IP addresses and ports on both sides is the definition in the TCP specification (the entries for connection and socket in the glossary in Section 4 of RFC 9293). Not covered: clients on another computer, and special socket options (such as SO_REUSEPORT) that let several programs share the same port.
Previous lab: Switches and routers · Next lab: TCP connections and retransmission