Dev Learning Lab

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

Fundamentals › Networking

TCP connections

What does it mean to open a connection, and what happens if you send without one?

TCP and UDP are two sets of rules for two programs to send text (bytes) to each other over a network. To send with TCP, the sending program must first run a line that says "connect to port 9000 of 127.0.0.1" and open a connection to the receiving program. The connection is opened only when the receiving program has that port open and is waiting, and the text sent after that arrives in the order it was sent. UDP has no line for connecting. Each line that sends text names where to send it and just throws it out. In this lab you switch the way of sending between TCP and UDP, add or remove the receiving program, and see what the sender gets and what the receiver gets. The code box is not a real program; it describes in words what the two programs do, and the number 9000 is an example. A port is a number that tells programs apart inside one computer, and the address 127.0.0.1 points to this computer itself.

Checked against real execution · Ran all 4 combinations on 127.0.0.1 with net and dgram of Node.js 24.18.0 and checked against the results

Concepts in this lab

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.
TCP connection
A TCP connection is the path that the sender and the receiver open between them before they exchange text with TCP (it is not a line that is actually laid down, but an agreement in which the two sides remember the state of each other). The sender asks for a connection to the IP address and the port of the other side, and if a program has that port open and is waiting, the connection is opened. The procedure for opening a connection is the 3-way handshake (RFC 9293 section 3.5). After the connection is opened, TCP takes care of delivering the bytes in the order they were sent, with nothing missing (RFC 9293 section 2.2 says that TCP provides a reliable, in-order, byte-stream service). Without a connection, text cannot be sent. HTTP/1.1 also goes over such a reliable connection, and the default for an http address is TCP (RFC 9112 section 9).
Connection refused error
A connection refused error is the error that the sender gets when it asks for a TCP connection but no program has that port open and is waiting. In Node.js, the error event comes instead of the connect event, and the error code appears as ECONNREFUSED (the Node.js errors documentation describes ECONNREFUSED as "Connection refused: No connection could be made because the target machine actively refused it", and the net documentation says that if there is a problem with the connection, error comes instead of connect). Because the connection was not opened, not a single letter of text is sent. The TCP standard says to send a reset signal (RST) to a request that comes with no connection (RFC 9293 section 3.5.2).
Sending with UDP and delivery confirmation
With UDP, you do not open a connection; each time you send text, you name where to send it (an IP address and a port) and just send it out. The UDP standard says that with this way, delivery and duplicate protection are not guaranteed (RFC 768 introduction). So the "no error" that the sender gets only means that the text left this computer; it does not mean that the other side got it. The Node.js dgram documentation says only that the callback of send reports a DNS error or tells when the buffer that holds the text can be written again, and does not say that it is a confirmation that the receiver got it. Even when there is no receiving program, the sender may get no error, and to confirm delivery, you have to make your own rule in the program in which the receiver sends back an answer.

Try these

Running with the default settings

  1. The receiving program runs the line "Open port 9000 with TCP and wait". This line asks the operating system, "When a TCP connection comes to port 9000 of this computer, give it to me." The sending program has not done anything yet.
  2. The sending program runs the line "Connect to port 9000 of 127.0.0.1 with TCP". The address 127.0.0.1 points to this computer itself, and port 9000 is the number that a receiving program opened on that computer. TCP first opens a connection like this before it sends text. The three letters A, B, C have not been sent yet.
  3. A program has opened port 9000, so the connection is opened. The receiving program got one connection, and the sending program is told that the connection succeeded. Now there is one path between the two programs, and the text sent next goes through this path. The exchange of confirmations between the two operating systems when they open a connection is covered in the in-depth lab "TCP connections and retransmission".
  4. The sending program runs the three lines "Send text" one after another and sends the three letters A, B, C through the connection. All three were sent without an error.
  5. The receiving program gets the text that came through this connection. The text it got is ABC, exactly in the order it was sent. TCP takes care that the bytes sent through a connection arrive in the order they were sent.
  6. What the sender saw is "connected" and "no error". With TCP, if no one is there, it fails at the connecting step, so an opened connection means that the receiving program is there.

Result of this run

Code

# Receiving program
Open port 9000 with TCP and wait

# Sending program
Connect to port 9000 of 127.0.0.1 with TCP
Send text: "A"
Send text: "B"
Send text: "C"

Assumptions of this model

The sending program and the receiving program were made with the net module (TCP) and the dgram module (UDP) of Node.js 24.18.0 (Windows 11), and they were actually run on 127.0.0.1. The code box is not the source of these programs; it describes in words what each program does, and what was checked is whether those lines are the same as the actions that were actually run (whether the receiver opened the port and which protocol, whether there was a call that connects, and the order of the text sent). All 4 combinations were run 5 times each, and the results of the 5 runs were the same. What was checked is what the sender got (whether the connection succeeded, the error code, and the number of sends that finished without an error), the text the receiver got and the number of connections it got, and the time from the connection request until the result came out. The 9000 on the screen is an example, and in the actual runs a different free number was chosen for each combination (for the combinations with no receiver, the text was sent to a number that had just been closed, and with TCP, that nobody actually had it open is confirmed by the connection refused). The sender sent A, B, C at intervals of 0.05 seconds. When the connection failed in TCP, the program was written to stop there and not run the sending lines. The error code ECONNREFUSED, and that there was no error in UDP, are what was observed on the PC used to write this lab (Windows 11), and they can differ by operating system. The result of the connection request (whether the connection succeeded or was refused) came out within 2 milliseconds at most on this PC, and this value is small because it is inside the same computer. Whether the sender knows that someone is there was decided in the same way, by whether what the sender saw is the same or different when the receiver was there and when it was not. TCP was different, a successful connection against a refused connection, and UDP was the same, because it sent three times without an error in both cases. However, whether an opened TCP connection also means a confirmation that the receiving program read the text that was sent was not covered in this lab, and the box on the screen says only whether someone is there. The text ABC that the receiver got was in the order it was sent for both protocols on this PC, but the standard fixes the order only for TCP (for UDP this was observed in a run inside the same computer on this PC, and the case of crossing the Internet was not looked at). How many reads the receiver uses to read the text sent with TCP was not covered (in this run it was read in three pieces, but we did not use that in any sentence). As a separate check, when we connected with TCP to the http server of Node.js and wrote an HTTP request by hand, the server received one request and answered 200 OK, and when we sent the same text with UDP, send finished without an error but the server did not receive the request. Whether the operating system actually sent a refusal signal (RST) when it refused the connection, and what signal the operating system sent back when there was no receiver in UDP, were not confirmed because we did not capture packets. From the documents, we opened and checked the following. Section 2.2 of RFC 9293 (TCP) says that TCP is connection-oriented and provides a reliable, in-order, byte-stream service, section 3.5 says that the procedure for opening a connection is the 3-way handshake, and section 3.5.2 says that a reset signal (RST) is sent to a request that comes with no connection (we could not open section 3.10 and after). The introduction of RFC 768 (UDP) says that delivery and duplicate protection are not guaranteed in UDP. Section 9 of RFC 9112 says that HTTP assumes reliable, in-order delivery and that the default connection for an http address is TCP. The Node.js documentation for net says that if there is a problem with the connection, an error event comes instead of the connect event, but we could not confirm the name ECONNREFUSED in the parts we opened, and the documentation for dgram says only that the callback of send reports a DNS error and tells when the buffer that holds the text can be written again, and does not say that it is a confirmation that the receiver got it. This lab covers only one TCP connection and sending with UDP. It does not cover the procedure for opening and closing a connection (3-way handshake, FIN), retransmission when text is lost, putting text back in order, or flow control and congestion control, which are covered in the in-depth labs "TCP connections and retransmission" and "TCP and UDP". There is also a way to call connect on a UDP socket, but it does not open a connection as TCP does, and it was not used here.

Previous lab: IP addresses and ports · Next lab: URLs

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these