These days I see very often DevOps Engineers, Cloud Engineers, SysOps, and more focusing on Cloud services and new features but I feel we shouldn't forget about the basics and I also feel that the basics are imperative for when it comes to build a Landing Zone in the Cloud, regardless of what provider you use. Networking performance and its reliability are two of the main building blocks on which we setup our environment. For this reason, today, I want to go through the basics of our communications and talk about TCP as transport protocol. Setting expectations, there is no way I can summarise and talk about every single feature available with the TCP protocol, I'd need a book to do that, and this is not a book. I will try to talk about a collection of features which I believe are the basic more often used when dealing with troubleshooting and implementing networks on-prem - but also in the Cloud...
TCP (Transmission Control Protocol) is a fundamental protocol in computer networking that enables reliable communication between devices over IP networks. It forms the foundation for most internet-based applications, including web browsing, email, file transfers, and more.
As a network engineer and since I was a kid, I have always been passionate about understanding the basic fundamentals of TCP/IP, and like I mentioned already, I firmly believe that it serves as a cornerstone for anyone working in the field of networking... but not only in on-prem networking. In fact, it is essential for every network engineer and/or anybody working with Cloud to grasp how this protocol works before moving on to more advanced topics.
So... why is TCP important? TCP is crucial because it provides the necessary foundation for comprehending other networking concepts and protocols. TCP's reliability, congestion control, and flow control mechanisms are essential for ensuring the efficient and stable transmission of data across networks. By understanding TCP's inner details and features, engineers gain insights into the challenges and complexities associated with network communication, and they can apply this knowledge to troubleshoot and optimize network performance.
TCP's connection-oriented communication model, established through the "Three way Handshake", guarantees that data is transmitted reliably and in the correct order. The sliding window protocol, coupled with sequence numbers and acknowledgements, ensures that data loss is minimized, and any missing or corrupted packets can be retransmitted. Moreover, TCP's congestion control mechanisms play a pivotal role in maintaining network stability by dynamically adjusting the transmission rate to prevent network congestion.
As an aspiring network engineer or aspiring cloud engineer, it is crucial to recognize the significance of TCP/IP as a fundamental protocol. By delving into its intricacies and understanding its key features and mechanisms, you can build a solid foundation upon which to explore more advanced networking topics. TCP/IP knowledge not only enhances your understanding of network communication but also equips you with the skills needed to troubleshoot network issues, optimize performance, and design reliable and scalable network architectures. And let's not forget about the usual "DevOps expression: the issue is always related to networking", well... this is NOT true and I hope if you are reading this post, you will be able to understand why by the end of the article.
In this blog post, we will dive deep into the inner workings of TCP, demystifying its complex mechanisms and shedding light on its core concepts. By exploring the fundamentals of TCP, I want to provide you with a comprehensive understanding of the protocol. So, too much intro, let's start...
The following topics will be covered in our discussion today:
1. TCP Basics
TCP is a crucial component of the TCP/IP protocol suite and plays a vital role in enabling reliable communication between devices over IP networks. Let's explore the key aspects of TCP and its fundamental mechanisms.
1.1 Understanding the TCP/IP stack:
The TCP/IP protocol suite is a collection of networking protocols that facilitate communication between devices over the internet. TCP resides in the transport layer of the TCP/IP stack, sitting above the network layer (IP) and below the application layer.
Here is a visual representation of the OSI Model where you can identify the TCP stack:
+-----------------------------------+
| Application Layer |
+-----------------------------------+
| Presentation Layer |
+-----------------------------------+
| Session Layer |
+-----------------------------------+
| Transport Layer | - TCP / UDP
+-----------------------------------+
| Network Layer |
+-----------------------------------+
| Data Link Layer |
+-----------------------------------+
| Physical Layer |
+-----------------------------------+
1.2 Connection-oriented communication:
TCP employs a connection-oriented communication model, meaning it establishes a reliable and acknowledged connection between a sender and receiver before data transmission occurs. This process involves a three-way handshake and a four-way handshake for connection establishment and termination, respectively.
Here's an illustration of the three-way handshake:
Client Server
| |
SYN (SYN=1) SYN-ACK (SYN=1, ACK=1)
| |
ACK (ACK=1) |
| |
Connection Established
And here's an illustration of the four-way handshake for connection termination:
Client Server
| |
FIN (FIN=1) ACK (ACK=1)
| |
... FIN (FIN=1)
| |
ACK (ACK=1) ACK (ACK=1)
| |
Connection Closed
1.3 Packet structure:
TCP packets, also known as segments, consist of a header and payload. The header contains various fields that provide important information for reliable data transfer. Some of the key fields include:
Source Port: Specifies the port number of the sending application.
Destination Port: Indicates the port number of the receiving application.
Sequence Number: Provides a unique identifier for each TCP segment to ensure ordered delivery.
Acknowledgment Number: Acknowledges the receipt of data and indicates the next expected sequence number.
Data Offset: Specifies the length of the TCP header in 32-bit words.
Control Flags: These flags include various control and status bits such as SYN, ACK, FIN, etc.
Window: Indicates the receiver's buffer size for flow control.
Checksum: Helps ensure data integrity during transmission.
Urgent Pointer: If the URG flag is set, then this 16-bit field is an offset from the sequence number indicating the last urgent data byte.
Options: Additional fields that can be included for specific purposes, such as window scaling, timestamps, etc.
The data section of a TCP packet, also known as the payload, carries the actual information being transmitted. It can vary in size and content, depending on the application layer protocols being used. For example, in web browsing, the data section would contain the HTML, CSS, or JavaScript files associated with a webpage.
By understanding the structure of the TCP header and the nature of the data section, network engineers can analyze and interpret network packets effectively, troubleshoot issues, and optimize network performance
Here's an example of a TCP Header:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |C|E|U|A|P|R|S|F| |
| Offset | |W|C|R|C|S|S|Y|I| Window |
| | |R|E|G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (if any) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Understanding the TCP packet structure and its fields is vital for analyzing network traffic, diagnosing issues, and optimizing network performance.
By grasping the basics of TCP, including its position in the TCP/IP stack, connection-oriented communication model, and packet structure, you can gain a solid foundation for further exploration and comprehension of advanced networking concepts.
2. Reliable Data Transfer
One of the key features of TCP is its ability to provide reliable data transfer between communicating devices. Let's not forget after all, this protocol is a connection oriented protocol, we can also use UDP as transport protocol, this sits at layer 4 in the OSI model but it is not connection oriented, I won't dive deep in UDP on this post but it is worth mentioning, I will elaborate a bit more later. TCP achieves reliability through various mechanisms and protocols that ensure data integrity and ordered delivery. Let's explore the fundamental aspects of reliable data transfer in TCP.
2.1 Sliding Window Protocol:
TCP uses a sliding window protocol to manage the flow of data between the sender and the receiver. The sender maintains a sliding window that represents the range of sequence numbers it is allowed to send without receiving acknowledgements. As acknowledgements are received, the window slides forward, allowing the sender to transmit new data.
The sliding window mechanism allows for efficient and continuous data transmission, ensuring that the sender does not overwhelm the receiver with an excessive amount of data.
2.2 Sequence Numbers and Acknowledgements:
TCP assigns a unique sequence number to each byte of data transmitted. Sequence numbers help in ordering the segments at the receiver's end and detecting missing or out-of-order segments.
Acknowledgements (ACKs) are used to confirm the successful receipt of data. The receiver sends ACK packets to the sender, indicating the next expected sequence number. If the sender does not receive an ACK within a certain timeout period, it assumes that the segment was lost or corrupted and retransmits it.
Through sequence numbers and acknowledgements, TCP ensures that data is reliably transmitted, received, and reconstructed in the correct order.
2.3 Flow Control:
Flow control is a crucial aspect of reliable data transfer in TCP. It ensures that the sender does not overwhelm the receiver with more data than it can handle. TCP employs a sliding window mechanism for flow control.
The receiver advertises its available buffer space through the window size field in the TCP header. The sender adjusts its transmission rate based on the receiver's window size, ensuring that it does not send data faster than the receiver can process. This prevents congestion and optimizes the overall performance of the communication.
Flow control helps maintain a balance between the sender and receiver, ensuring that neither end becomes overwhelmed or experiences unnecessary delays.
Reliable data transfer is a fundamental aspect of TCP and allows for error-free, in-order delivery of data. The sliding window protocol, sequence numbers, acknowledgements, and flow control mechanisms work together to guarantee the reliability of TCP transmissions.
If you build with these concepts in mind, you can design and optimize TCP-based applications, diagnose and troubleshoot network issues related to reliable data transfer, and ensure efficient and reliable communication over IP networks.
2.4 MSS (Maximum Segment Size):
TCP MSS refers to the largest amount of data, measured in bytes, that a TCP segment can carry within a single network packet. It determines the maximum size of the payload that can be transmitted in each TCP segment. When a TCP connection is established between two hosts, they negotiate an MSS value during the TCP handshake process. This negotiated value is typically based on the capabilities of the network devices along the communication path. The MSS value helps optimize data transmission by ensuring that TCP segments fit within the Maximum Transmission Unit (MTU) of the underlying network, reducing the need for packet fragmentation and improving overall network efficiency and reliability.
Here is a simple code example in Python that demonstrates how to calculate the TCP MSS based on the Maximum Transmission Unit (MTU) and the TCP header size:
# python
def calculate_tcp_mss(mtu, tcp_header_size):
return mtu - tcp_header_size
# Example usage
mtu = 1500 # Maximum Transmission Unit (in bytes)
tcp_header_size = 40 # TCP header size (in bytes)
tcp_mss = calculate_tcp_mss(mtu, tcp_header_size)
print("TCP MSS:", tcp_mss)
In this example, the `calculate_tcp_mss` function takes two parameters: `mtu` (the Maximum Transmission Unit) and `tcp_header_size` (the size of the TCP header). It subtracts the TCP header size from the MTU to calculate the TCP MSS value. The result is then printed to the console.
Please note that the TCP header size may vary depending on the specific implementation and options being used. In this example, I simply assumed a TCP header size of 40 bytes for simplicity. Also, by default MTU value are 1500, having said that, some networking tech will benefit from manipulating the size according to application and/or other factors. I won't be going into details for MTU but if you like to have a deep dive into those topics, please let me know in the comments below.
3. TCP Congestion Control
TCP's congestion control is crucial for maintaining network stability and preventing congestion-related issues. It dynamically adjusts the transmission rate based on network conditions, aiming to alleviate congestion and ensure reliable data transfer. Let's explore TCP's congestion control mechanisms with an example.
Imagine a scenario where a sender is transmitting data to a receiver over a congested network. TCP employs various algorithms and mechanisms to detect and respond to network congestion effectively.
3.1 Slow Start and Congestion Avoidance Algorithms:
At the beginning of the data transfer, TCP enters the slow start phase. The sender starts with a conservative transmission rate and gradually increases it to probe the available network capacity. It exponentially increases the congestion window size, which determines the number of unacknowledged packets allowed in-flight.
For example, if the sender starts with a congestion window size of 1, it sends one packet and waits for an acknowledgment. Upon receiving the acknowledgment, the congestion window size is doubled to 2, allowing two packets to be sent. This process continues, exponentially increasing the congestion window size until congestion is detected.
When congestion is detected, such as through packet loss or increased round-trip times, TCP switches to the congestion avoidance phase. In this phase, the sender linearly increases the congestion window size instead of exponentially. This cautious approach helps prevent further congestion and maintains a stable network.
For instance, if the congestion window size is 10 and congestion is detected, TCP might reduce the congestion window size to 5 to alleviate congestion and prevent further packet loss.
3.2 Congestion Detection and Recovery:
TCP employs mechanisms to detect and recover from network congestion. One method is timeout-based retransmission. If an acknowledgment for a transmitted segment is not received within a certain timeout period, TCP assumes that the segment was lost and retransmits it. How many times happened to you while analyzing packet captures on Wireshark or on your tool of choice to see SYN Retransmits?
For example, if the sender transmits a segment and does not receive an acknowledgment within the expected timeframe, it assumes the segment was lost due to congestion. TCP then retransmits the lost segment to ensure reliable delivery.
Another mechanism used is fast retransmit. If the sender receives duplicate acknowledgments (ACKs) for the same segment, it infers that there is a segment loss. For instance, if the sender receives three duplicate ACKs for a specific segment, it assumes that the following segment was lost. TCP performs a fast retransmit, immediately retransmitting the presumed lost segment without waiting for the timeout.
Furthermore, TCP reduces the congestion window size and halves the transmission rate when congestion is detected. This helps alleviate network congestion and prevent further congestion-related issues.
By actively detecting and responding to network congestion, TCP adapts its transmission rate to ensure reliable data transfer while minimizing the impact of congestion on network performance.
Understanding TCP's congestion control mechanisms is vital for anybody who wants to optimize network performance, diagnose congestion-related issues, and design resilient network architectures that can effectively handle varying network conditions.
4.TCP Options and Extensions
TCP provides options and extensions that enhance its functionality and performance in specific scenarios. These options enable additional features and optimizations beyond the basic TCP protocol. Let's explore some common TCP options and extensions with a code example.
4.1 Window Scaling:
The window scaling option allows TCP to support larger window sizes, enabling improved throughput and better network utilization. It is particularly useful for high-speed connections or networks with large bandwidth..
In TCP, the window size field in the TCP header specifies the receiver's buffer size. The window scaling option expands the range of window sizes that can be negotiated between the sender and receiver.
Here's an example of how window scaling can be enabled using the `socket` API in Python
# python
import socket
# Create a TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Enable window scaling option
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_WINDOW_SCALE, 1)
# Bind and listen on a specific port
server_address = ('', 8080)
sock.bind(server_address)
sock.listen(1)
# Accept incoming connections
connection, client_address = sock.accept()
# ...
# Perform data transmission and reception
# ...
# Close the connection
connection.close()
sock.close()
By enabling window scaling, TCP can effectively utilize the available network capacity and optimize data transfer performance for high-speed or long-distance connections. This is particularly useful in an era where majority of users have at least 100Mbps home connectivity on average.
4.2 Selective Acknowledgement (SACK):
The selective acknowledgement (SACK) option allows TCP to recover from multiple packet losses more efficiently. With SACK, the receiver can inform the sender about the specific segments that have been received successfully and those that are missing.
This enables the sender to retransmit only the missing segments, instead of retransmitting the entire window of data. It reduces unnecessary retransmissions and improves overall network efficiency.
SACK is typically negotiated during the TCP connection establishment phase. Once enabled, it can be used to enhance TCP's ability to recover from packet loss.
Here's an example of using the `SOL_TCP` socket option to enable SACK in Linux:
# python
import socket
# Create a TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Enable SACK option
sock.setsockopt(socket.SOL_TCP, socket.TCP_SACK, 1)
# Bind and listen on a specific port
server_address = ('', 8080)
sock.bind(server_address)
sock.listen(1)
# Accept incoming connections
connection, client_address = sock.accept()
# ...
# Perform data transmission and reception
# ...
# Close the connection
connection.close()
sock.close()
By using the SACK option, TCP can efficiently recover from packet loss, leading to improved throughput and reduced retransmission overhead.
These are just a couple of examples of TCP options and extensions. TCP provides various other options and extensions, such as timestamps and Performance Enhancing Proxies (PEP), which can further enhance performance and accommodate specific network requirements. I won't be going in details as I promised at the beginning of this post to keep it simple and basics, but again if you think expanding on those subjects might be useful, feel free to leave a comment.
By leveraging these TCP options and extensions, you can tailor TCP's behavior to specific scenarios and optimize network performance based on the unique characteristics of their applications and networks.
5. TCP vs UDP
As I promised some lines above.. I will now try to point out the basics differences between TCP and UDP (User Datagram Protocol). These protocols sits both at Layer 4 in the OSI Model and are two widely used transport layer protocols in computer networking. While both protocols facilitate communication between devices over IP networks, they differ in their characteristics, use cases, and reliability. Let's start...
5.1 Characteristics and Use Cases:
TCP is a connection-oriented protocol, meaning it establishes a reliable and acknowledged connection between the sender and receiver before data transfer. It ensures that data is delivered in order and without loss or corruption. TCP is well-suited for applications that prioritize reliability, such as web browsing, email, file transfers, and other applications that require the guaranteed delivery of data.
UDP, on the other hand, is a connectionless protocol that provides a simple, best-effort delivery mechanism. It does not establish a connection before data transfer and does not guarantee reliability or ordered delivery. UDP is suitable for applications that prioritize speed and low latency over reliability, such as real-time streaming, video conferencing, online gaming (some), and DNS (Domain Name System) queries (although DNS can also use TCP in specific cases, but again, today is not "DNS day"...).
5.2 Reliability and Error Checking:
TCP provides reliable data transfer by employing mechanisms such as sequence numbers, acknowledgements, and retransmission of lost packets. It ensures that data is delivered correctly and in order. TCP also performs error checking through checksums to detect and correct errors in the transmitted data. It sounds great doesn't it? but UDP also have its use cases!
UDP, being a connectionless protocol, does not provide built-in reliability mechanisms like TCP. It does not perform automatic retransmissions or ordered delivery. UDP relies on higher-level protocols or applications to handle error checking and reliability if required.
5.3 Congestion Control:
TCP includes built-in congestion control mechanisms to regulate the transmission rate and avoid network congestion. It dynamically adjusts the rate based on network conditions to prevent network overload and maintain stability.
UDP does not have congestion control mechanisms built into the protocol. Applications using UDP are responsible for implementing their own congestion control mechanisms if needed. This allows for more control and flexibility but also requires careful design and management to avoid network congestion.
5.4 Comparison Summary:
So, let's summarize the differences between TCP and UDP:
- TCP is connection-oriented, while UDP is connectionless.
- TCP provides reliable, ordered delivery, whereas UDP does not guarantee reliability or ordered delivery.
- TCP performs error checking and automatic retransmission, while UDP relies on applications for error checking and recovery.
- TCP includes built-in congestion control mechanisms, while UDP requires application-level congestion control.
- TCP is suited for applications that prioritize reliability, while UDP is preferred for applications that prioritize speed and low latency.
Choosing between TCP and UDP depends on the specific requirements of the application. If reliability and ordered delivery are crucial, TCP is a better choice. For applications that prioritize speed and low latency, and where occasional data loss is acceptable, UDP is more suitable.
Understanding the differences between TCP and UDP allows network engineers to select the appropriate protocol for their applications, optimize network performance, and ensure reliable communication based on specific requirements.
Conclusions / Call for Actions
TCP is a fundamental protocol in computer networking, enabling reliable communication between devices over IP networks. We discussed TCP's position in the TCP/IP protocol suite, its connection-oriented communication model, and the structure of TCP packets. We also went through concepts of reliable data transfer mechanisms, including the sliding window protocol, sequence numbers, and acknowledgements, as well as TCP's congestion control mechanisms.
Additionally, we examined some of the TCP options and extensions such as window scaling and selective acknowledgement (SACK) that enhance TCP's functionality and performance. Lastly, we compared TCP with UDP (User Datagram Protocol), highlighting their differences, use cases, and reliability.
Of course, I can't go through every single details and feature as I would need a book and not a blog post to do so but I hope this was somehow useful, I would like to leave you with a quick exercise to play with which will showcase the differences between TCP and UDP in practice. I am a strong believer of hands on exercises so when I can, I always play with tech.
Here's an example Python script that demonstrates TCP and UDP client-server communication:
TCP Server
# python
import socket
# Create a TCP socket
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to a specific address and port
tcp_server_address = ('localhost', 8080)
tcp_server_socket.bind(tcp_server_address)
# Listen for incoming connections
tcp_server_socket.listen(1)
print("TCP server is listening...")
# Accept a client connection
tcp_client_socket, tcp_client_address = tcp_server_socket.accept()
print("Accepted TCP connection from:", tcp_client_address)
# Receive data from the client
tcp_data = tcp_client_socket.recv(1024)
print("Received TCP data:", tcp_data.decode())
# Send a response to the client
tcp_response = "Hello from TCP server!"
tcp_client_socket.send(tcp_response.encode())
# Close the TCP socket
tcp_client_socket.close()
tcp_server_socket.close()
UDP Server:
# python
import socket
# Create a UDP socket
udp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Bind the socket to a specific address and port
udp_server_address = ('localhost', 8081)
udp_server_socket.bind(udp_server_address)
print("UDP server is listening...")
while True:
# Receive data from the client
udp_data, udp_client_address = udp_server_socket.recvfrom(1024)
print("Received UDP data:", udp_data.decode())
# Send a response to the client
udp_response = "Hello from UDP server!"
udp_server_socket.sendto(udp_response.encode(), udp_client_address)
TCP Client
# python
import socket
# Create a TCP socket
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to the TCP server
tcp_server_address = ('localhost', 8080)
tcp_client_socket.connect(tcp_server_address)
# Send data to the server
tcp_data = "Hello from TCP client!"
tcp_client_socket.send(tcp_data.encode())
# Receive the server's response
tcp_response = tcp_client_socket.recv(1024)
print("Received TCP response:", tcp_response.decode())
# Close the TCP socket
tcp_client_socket.close()
UDP Client
# python
import socket
# Create a UDP socket
udp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Server address and port
udp_server_address = ('localhost', 8081)
# Send data to the server
udp_data = "Hello from UDP client!"
udp_client_socket.sendto(udp_data.encode(), udp_server_address)
# Receive the server's response
udp_response, udp_server_address = udp_client_socket.recvfrom(1024)
print("Received UDP response:", udp_response.decode())
# Close the UDP socket
udp_client_socket.close()
Implementation Guide:
Open a text editor or an Integrated Development Environment (IDE) of your choice.
Create a new Python script file and give it a relevant name, such as "tcp_udp_communication.py".
Copy and paste the TCP server code into the script file.
Save the file.
Open a terminal or command prompt and navigate to the directory where the script file is saved.
Run the script by executing the command: python tcp_udp_communication.py.
The TCP server will start listening on port 8080.
Open a new terminal or command prompt for the TCP client.
Copy and paste the TCP client code into the new terminal or command prompt.
Save the file with a different name, such as "tcp_client.py".
Update the TCP server address if necessary, ensuring it matches the address in the TCP server script.
Run the TCP client script by executing the command: python tcp_client.py.
The TCP client will establish a connection with the TCP server, send a message, and receive a response.
Observe the output in the terminals or command prompts to see the interaction between the TCP client and server.
Close the TCP client and server by pressing Ctrl + C in their respective terminals or command prompts.
Repeat steps 3-7 for the UDP server script, using a different port (e.g., 8081).
Repeat steps 9-14 for the UDP client script, ensuring the UDP server address matches the UDP server's address.
Observe the output in the terminals or command prompts to see the interaction between the UDP client and server.
Close the UDP client and server by pressing Ctrl + C in their respective terminals or command prompts.
In the case of the TCP exercise, you will be seeing Server accepting connection first and then receiving data. This is because TCP is connection-oriented protocol. We first establish connectivity and then we exchange data.
In the case of UDP exercise, you will not be seeing the Server responding, this is because there is no connection establishment as the session is using UDP. This is because UDP is connectionless protocol.
My advise would also be to run the same exercise while running tcpdump or Wireshark to collect packet capture file and compare both conversations.
Again, I hope this was useful, hope you enjoyed the article, thanks so much for reading. If at least one of you learned at least 1 thing today, my goal was achieved :)
Comments