Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Fundamentals › Networking

IP addresses and ports

What do an IP address and a port each point to?

To connect to another program over a network, you need to know two things. An IP address is a number that points to "which computer", and a port is a number that points to "which of the programs running on that computer". In the code box, the server program asks the operating system for port 8080 with new ServerSocket(8080), opens it, and waits for a connection, and the client program connects with new Socket("127.0.0.1", 8080) to port 8080 of the computer 127.0.0.1 (this computer itself). In this lab, you do not start the server program, or connect to port 9090 that nobody has opened, or let another program open port 8080 that is already open, and you see what happens to the connection. The server and the client are different programs, so the code box shows the code of both programs together.

Checked against real execution · On JDK 21 (Windows 11), started a server, another program, and a client as separate processes and ran 8 combinations on 127.0.0.1 and checked them

Concepts in this lab

IP address (IPv4)
This is a 32-bit numeric address used to find a device on the internet. To make it easy for people to read, it is cut into 8-bit groups and written as four decimal numbers from 0 to 255, such as 192.168.0.10. The front part of the address shows which network the device is on, and the back part shows which device it is within that network. Where the front part ends cannot be known from the address alone; it is decided only together with a subnet mask.
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.
127.0.0.1 (localhost)
127.0.0.1 is the IP address that points to "the computer this code is running on". Every address that starts with 127 is a loopback address internal to the host, and RFC 1122 says that such an address must not appear outside the host (section 3.2.1.3). So data sent to this address does not leave the computer and reaches a program on the same computer. localhost is the name that points to this address, and RFC 6761 recommends that software that turns names into addresses turn localhost into the loopback address (section 6.3). You use it when you run a server and a client together on one computer, and the 127.0.0.1 of your computer cannot be reached from another computer.

Try these

Running with the default settings

  1. The server program starts and runs the line new ServerSocket(8080). This line asks the operating system, "give me the connections that come to port 8080". The operating system accepts the request, so now the program that has opened port 8080 on this computer is the server program.
  2. It runs the line server.accept(). accept is a method that waits until a connection comes, so the server program stops at this line and waits for a connection.
  3. The client program runs the line new Socket("127.0.0.1", 8080). 127.0.0.1 is the address that points to the computer this code is running on (the name localhost means this address), and 8080 is the port number of the program on that computer that it wants to connect to. An IP address points to which computer and a port points to which program on that computer, so the client asks to connect to port 8080 of this computer.
  4. The operating system looks for the program that has opened port 8080. The server program opened it, so the operating system hands the connection to the server program. The server's server.accept() line finishes, and it returns a socket for exchanging text over this connection and puts it in fromClient.
  5. The socket on the client side also has a port number of its own. The code never set it, yet it had a number different from the server's port (all the numbers we saw in the checking runs were 49152 or higher). One connection is told apart by the pair of IP addresses and ports at its two ends.
  6. The server program writes "Hello" to fromClient (write) and closes this connection with fromClient.close().
  7. The client's readAllBytes reads all the text that comes until the connection is closed. The client puts "Hello" in text and println prints it.

Result of this run

Code

// Server program: open port 8080 and wait for a connection
ServerSocket server = new ServerSocket(8080);
Socket fromClient = server.accept();
fromClient.getOutputStream().write("Hello".getBytes("UTF-8"));
fromClient.close();

// Client program: connect to 127.0.0.1 (this computer)
Socket socket = new Socket("127.0.0.1", 8080);
String text = new String(socket.getInputStream().readAllBytes(), "UTF-8");
System.out.println(text);

Assumptions of this model

Java is JDK 21.0.12.1 and the operating system is Windows 11. For all 8 combinations, we made the sources of the server program, another program, and the client program from the same text as the code on the screen, compiled them, started the java of this JDK as separate processes, and checked against the result of actually connecting on 127.0.0.1. What we checked is whether the client's connection succeeded and the kind of exception thrown, the text the client received, and whether the program that tried to open the port again opened it and the kind of exception thrown. 8080 and 9090 on the screen are example numbers, and in the actual check we picked two other numbers that were free on this PC for each combination and used them in the 8080 slot and the 9090 slot (for the 9090 slot, we tried to connect and confirmed that nobody had opened it). The code on the screen leaves out the import lines, the main method, and the exception handling (passed on with throws Exception), and the real programs have one more output line that tells that the process is ready. The only connection between the server and the client that we really made was on 127.0.0.1, and we did not connect to an external network. However, new ServerSocket(port) opens in a form that accepts connections on all addresses of this computer (netstat also showed 0.0.0.0), so during the check the server program was not bound to 127.0.0.1 only for a few seconds. The connection refusal and the "port already in use" error were returned by the operating system (Windows 11), and Java reported them as exceptions. When the connection was refused, what Java threw was java.net.ConnectException (message Connection refused: connect), and when it opened an already open port again, what it threw was java.net.BindException (message Address already in use: bind), and these messages were observed on this PC and may differ from one operating system to another. What we checked by execution is that right after the server opens the port, the list of the operating system (netstat) shows that port as belonging to the server process, that the own port of the client-side socket is a number of 49152 or higher different from the server port, that if only another program opens the port without the server, the client's connection succeeds but no text comes within 3 seconds and the client does not finish (we did not look at what happens after 3 seconds), and that even if the client connects to a port the server did not open, the server process keeps waiting. We did not capture packets, so we could not check with which signal the operating system actually refused the TCP connection request. For the documents, we opened the following directly and checked them. Section 2.2 of RFC 9293 (TCP) says that TCP tells application services apart by port numbers, section 3.1 says that the header has a source port and a destination port, section 3.4.1 says that a connection is identified by a pair of sockets (the two ends), and section 3.10.7.1 says that in the state with no connection (CLOSED), when a segment that does not carry RST arrives, it responds with RST (we could not confirm whether the refusal above is this). Section 3.2.1.3 (g) of RFC 1122 sets addresses that start with 127 as the internal host loopback address and says that they must not appear outside the host, and Table 4 in section 2.2.2 of RFC 6890 lists 127.0.0.0/8 as Loopback and marks it as an address that is not forwarded. Section 6.3 of RFC 6761 recommends that the name localhost be resolved to the loopback address (when we resolved localhost on this PC, we got 127.0.0.1 and ::1, the IPv6 loopback address, and this lab dealt with 127.0.0.1 only). The java.net.ServerSocket documentation (Java SE 21) says that it creates a server socket with a port number, that the queue length for connection requests that have not been accepted yet is 50, and that accept blocks until a connection comes. This documentation has no explanation of BindException or of a port already in use, and the constructor description in the java.net.Socket documentation does not mention ConnectException either, so the two exceptions are observations on this PC. A port here is a port for connecting over TCP, and we did not cover UDP, IPv6, a computer with several IP addresses, or connecting to another computer on the internet. The details of sockets and ports (ephemeral ports, the range of port numbers and well-known numbers, and so on) are covered in the in-depth lab "Sockets and ports".

Previous lab: Storage and durability · Next lab: TCP connections

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these