Original link: blog.csdn.net

Transmission Control Protocol (TCP) is a reliable and connection-oriented Transmission layer communication Protocol based on byte stream.

  • Ip-based: In the TCP/IP stack, TCP is transmitted over IP. The combination of the source port in a TCP packet, the source address in an IP packet, the target port in a TCP packet, and the target address in an IP packet uniquely identifies a TCP connection.

  • Connection-oriented and reliable: Unlike UDP, TCP establishes a TCP connection through a three-way handshake before transmitting data, then transmits data, and finally releases the connection through a four-way handshake. The connection here means that the two sides can perceive the existence of each other before they really start to interact, but it is not real, it is virtual. The REPRESENTATION of a TCP connection on two computer operating systems is a state maintained by both parties through certain data structures. In addition, TCP uses sequence control, retransmission mechanism, flow control, congestion control and so on to ensure the reliability of communication.

  • Based on byte streams that flow is uninterrupted data structure, the meaning of here have no fixed message boundaries, only if send content is large, TCP will cut into section by section, the data into a kernel buffer, and finally a message send how many bytes of data are uncertain (could be MTU, MSS, send window size, the congestion window size, etc). For example, the write function is called twice to write two batches of data into the socket. The first batch of data is 600 bytes and the second batch of data is 800 bytes. The write function only copies the data into the kernel buffer.

    Two packets may be sent, the first 600 bytes (the first batch of data) and the second 800 bytes (the second batch of data);

    One packet may be sent, consisting of 600 bytes (the first batch of data + the second batch of data).

    Two packets may be sent, the first 1000 bytes (600 bytes of the first batch of data + 400 bytes of the second batch of data) and the second 400 bytes (400 bytes of the second batch of data);

    Two packets may be sent, the first 300 bytes (300 bytes of the first batch of data) and the second 1100 bytes (300 bytes of the first batch of data + 800 bytes of the second batch of data);


TCP packet


A protocol is an “agreement” reached in advance when computers communicate with each other through a network. Before we learn about TCP packets, we will review the OSI 7-layer model and TCP/IP protocol.

OSI (Open System Interconnect), Open System interconnection, commonly known as its OSI reference model, it is ISO (International standardization organization) in order to better popularize the network and launched specifications. OSI defines seven layers of network interconnection framework: physical layer, data link layer, network layer, transmission layer, session layer, presentation layer and application layer. Each layer implements its own protocol and function and realizes network communication with neighboring layers.

TCP/IP refers to a protocol cluster consisting of HTTP, FTP, SMTP, TCP, UDP, and IP, not only TCP and IP. As for why it is called TCP/IP, I guess TCP and IP are more representative

As for the difference between the OSI reference model and TCP/IP Layer 4 protocol, I understand that the OSI reference model is a standard defined academically and is a theoretical network communication model without detailed definition of the protocol. The TCP/IP protocol is a specific implementation of this standard reference, is in the actual implementation of the network protocol running. The OSI reference model focuses on “what are the necessary functions of the communication protocol”, while TCP/IP puts more emphasis on “what programs should be developed to implement the protocol on the computer”.

Curl -h “content-type :application/json” -x POST –data ‘{“param1”: “value2”, “param2”: “Value2”} ‘http://192.168.2.188/service, for example, to analyze through the HTTP protocol from the client to the server to send data, how the data transmission:

The client is the sender and the server is the receiver.

{“param1”: “value2”, “param2”: “Value2 “}] in the HTTP BODY to form an HTTP message.

2. The transport layer takes the received HTTP packet as the CONTENT of TCP, adds the TCP header (including the source port number and target port number), and splices it into a data segment (TCP packet). If the TCP content (HTTP packet) is large, the transport layer may splice the TCP content into multiple parts and splices the data segment (TCP packet).

3. The network layer adds the IP header (including the source IP address and destination IP address) to the received TCP packet to form a packet (IP packet).

4. The data link layer adds Ethernet header (including source MAC address, target MAC address, etc.) and Ethernet tail (FCS frame inspection sequence) to the received IP packet to form a data frame.

5. Data frames in the data link layer will be converted into bitstreams through the physical layer after encapsulation and transmitted on the physical media. Bitstream is binary stream (01010101010101010101010101), in the medium is in the form of a current of high level in the form of transport.

The sender transmits data from the application layer, transmission layer, network layer, and data link layer from top to bottom, while the receiver transmits data from the data link layer, network layer, transmission layer, and application layer from bottom to top to each upper layer. At each layer, the header information necessary for the protocol at the current layer can be attached to the data transmitted from the previous layer. Then, the receiving end separates the data “header” and “content”, forwards the data to the previous layer, and finally restores the data at the sending end.


TCP three handshakes, four waves


TCP is connection-oriented transmission. The communication parties establish a “connection” through a three-way handshake. The “connection” refers to that the communication parties know the existence of each other, have corresponding socket resources, send cache and receive cache, and have corresponding congestion control policies. The connection is not a real thing, but a state that is maintained by the two communicating parties through certain data structures.

Before analyzing the three-way handshake, you may understand the CONTENT of TCP packets more easily.

  • Source port: the port number of the application corresponding to the client (sender). When an application initiates a network request, the operating system assigns a port number to the application

  • Destination port: Port number of the server (receiver) corresponding to the application. It is generally set when the listener is started. For example, port 8080 is used when a Tomcat is started

  • Sequence Number: The Sequence Number is related to the value of the SYN control flag bit.

    When SYN is 1, the current TCP packet is at the beginning of establishing a connection. The ISN is generated randomly based on the timer, source IP address, destination IP address, source port, and destination port.

    When SYN=0, data is officially transferred. When sending data, the client (sender) sets sequential sequence numbers for each TCP packet segment. The sequence number of the current packet segment is the sequence number of the first byte of the sent data. Such as the client to send three consecutive segments, each TCP packet carries the data length is 2 bytes, namely three packets of data respectively, bytes 1 + 2 bytes 】 【 【 bytes 3 + 4 bytes 】, 【 5 bytes + 6 bytes, that the three segments corresponding to the serial number of 1, 3, 5 respectively

  • Acknowledgement Number: Indicates the Number of the next packet that the receiving end expects to receive from the sending end.

    Such as the client sends the length is 2 bytes of three message bytes 1 + 2 bytes, 】 【 bytes 3 + 4 bytes 】, 【 5 bytes + 6 bytes, namely the three segments corresponding to the serial number of 1, 3, 5, respectively, the corresponding response of three server message confirmation number 3, 5, 7, respectively, The client is told that it has received all data with serial number 3, please continue to send the data with serial number 3, received all data with serial number 5, please continue to send the data with serial number 5, received all data with serial number 7, please continue to send the data with serial number 7

  • Header length: indicates the length of the TCP header. The value indicates the multiple of 32 bits contained in the header. For example, if the TCP header contains 20 bytes (5 x 32 bits), the value is 5

  • Reserved: Reserved fields

  • Control bit: Each control bit is 1 byte

Sign a instructions
URG If the value is 1 bit, the emergency pointer field is valid. The URG bit indicates that the upper-layer entity (data) in the packet segment is marked as “urgent” data. When URG=1, the subsequent emergency pointer indicates the location (byte offset relative to the current sequence number) of the emergency data in the current data segment, and the TCP receiver must notify the upper-layer entity.
ACK ACK=1 indicates that the confirmation number field is valid. According to the TCP protocol, the ACK value of all packets sent after the establishment must be 1. When ACK=0, it indicates that the data segment contains no acknowledgement information. When ACK=1, it means that the packet segment includes an Acknowledgment Number for the successfully received packet segment, and this Number is also the expected Number of the next packet.
PSH Contains 1 bit, indicating that the current packet needs to request a push operation. When PSH=1, the receiver delivers the data to the upper layer as soon as it receives it, rather than until the entire buffer is full.
RST If RST is set to 1, the TCP connection is reset. Used to reset a connection that is out of order. Also used to reject an invalid data segment or reject a connection request. If the RST bit is set in the data segment, it indicates that the packet sender is faulty.
SYN 1 bit, used to synchronize serial number when connection is established. When SYN=1 and ACK=0, it indicates that this is a connection request packet. If the peer agrees to establish a connection, set SYN=1 and ACK=1 in the response packet. Collectively, SYN 1 indicates that this is a connection request or connection accept message.
FIN It is a bit that indicates the end of the sender bit stream and is used to release a TCP connection. If the FIN value is 1, the sender finishes sending data and requests to release the connection.
  • Options and fill section: This section is not mandatory, you can add the corresponding data as needed. Maximum segment Size (MSS) indicates the Maximum length of data segments in each TCP packet. MSS exists only in SYN packets (therefore, TCP negotiates the size of MSS in the three-way handshake). Generally, a larger VALUE of MSS results in higher network utilization. But it’s also possible to slow down your network. TCP determines the MSS value through the MTU. In the MTU, the size of an IP packet does not exceed 1500 bytes, and the header of an IP packet is 20 bytes. Therefore, the LENGTH of a TCP packet does not exceed 1480 bytes. The header of a TCP packet is 20 bytes. Therefore, the data carried by TCP does not exceed 1460 bytes. That is, the maximum MSS is 1460 bytes. MTU: the maximum control unit, the data link layer requires that the frame size cannot exceed 1518 bytes (14-byte frame header + 4-byte frame checksum + up to 1500 bytes of data). The 1500 bytes of data is MTU.




Three-way handshake

The three-way handshake establishes a connection:

When the communication parties establish a connection, the Server usually opens a ServerSocket first to listen to the connection request of the other party, which is called passive opening. After the Server is enabled, the Client can initiate a connection request to the Server. This is called active Opening.

1. The Client generates Sequence Number (suppose the GENERATED SEQ value is X) and sends a TCP request packet to the Server with the SYN flag bit set to 1. The connection is established and the Client enters the SYN-sent state. Server elder brother, I would like to request to establish a connection with you.

2. After the Server receives the SYN request in LISTEN state, it generates the Sequence Number (assuming the generated SEQ value is Y), sets the ACK bit to 1, and the SYN bit to 1. Acknowledgement Acknowledgement Number (ACK) is the SEQ +1 (X +1) of the Client’s first handshake packet, indicating that it has received the request from the other party and confirmed the establishment of a connection with the other party. Then the packet is sent to the Client. After that, the Server enters the SYN_RCVD state. At the same time, the Server creates a Socket to communicate with the Client and places it in the half-connection queue. [Client brother, I know, I agree to establish a connection with you]

3. After receiving the Server’s second handshake packet (FIN+ACK), the Client will reply a packet to the Server. The ACK flag bit is 1 and Acknowledgement Number (ACK) is the SEQ +1 (Y +1) of the Server’s second handshake packet. Indicates that the peer party has received the connection confirmation request and enters the ESTABLISHED state. After receiving the third handshake packet from the Client, the Server enters the ESTABLISHED state and puts the Socket into the full connection queue. Okay, I got it.

After the three processes are complete, each party agrees that the other is ready to receive the data, and the data transfer can begin.

[thinking]

  • Can a connection be considered successful after only two handshakes? Why do you need three handshakes?

    If the server sends the second FIN+ACK packet, the server considers the connection to be established successfully. If the second FIN+ACK packet is lost, the client considers the server to be not ready. If the server sends data to the client, The client discards all packets from the server until it receives the FIN+ACK packet for the second handshake, which is impossible.

    I understand that it needs to be at least 3 times, but it can also be 4 times, 5 times, 100 times, but 3 times is so that both the client and the server can ensure that the message has been sent to the other side and the response has been received. The first handshake, where the client applies to the server to establish a connection, is necessary; The second handshake is necessary to ensure that the client knows that the server has the resources to establish a connection with it. Otherwise, the client will assume that the server has not received the connection request. The third handshake is to ensure that the server knows that the client has agreed to establish a connection with the client. In this way, both sides of the message, are back and forth, basically achieve “reliable connection”.

  • What if the first handshake is broken? The Client does not receive an ACK packet from the Server and tries again

    After the FIN packet with the first handshake is interrupted, the Client retransmits the packet. The retransmission timeout duration (RTO) increases exponentially. For example, the retransmission timeout duration of the first handshake is 1s, the second seconds is 3s, the third seconds is 7s, the fourth seconds is 15s, and the fifth seconds is 31s. Retry times (tcp_syn_retries) The default value is five times and can be set in the system.

  • What if the second handshake is broken?

    If the Server interrupts sending a SYN or ACK packet to the Client for the second time, the Client considers that the first SYN packet may not reach the Server and resends the first SYN packet. Then, the Server considers that the SYN and ACK packets it sends to the Client are lost and retransmits the SYN and ACK packets it sends to the Client. The retransmission times (TCP_synack_retries) is five times by default.

  • What if the handshake is broken for the third time?

    If the handshake is interrupted for the third time, the Server considers that it failed to send the SYN and ACK packets of the second time. Therefore, the Server retransmits the SYN and ACK packets of the second time. If the number of retransmission times exceeds the maximum value, the Server disconnects the connection and the state changes from SYN_RCVD to CLOSED. The Client is already in the ESTABLISHED state and can send data. However, the Server is not in the ESTABLISHED state and does not receive the data sent by the Client. Therefore, the Client retransmits the data. After the number of retransmission times (TCP_retries2) of the sent data is exceeded, the Client automatically disconnects.


TCP waved four times

Four waves of disconnection:







2. After receiving a FIN packet from the Client, the Server sends an ACK packet back. The ACK bit is 1 and Acknowledgement Number (ACK) is the SEQ +1 (x+1) of the Client’s first wave packet. [Received, please wait a moment, brother client, I will talk to you when I am ready]

3. When the Server can be disconnected (there is no task in hand), the Server sends a FIN packet with the FIN bit set to 1 and the ACK bit set to 1 to the Client. Sequence Number Sequence Number is the ACK value of the last ACK packet sent by the Client during communication with the Client (assuming seq= Z), and Acknowledgement Number (ACK) is the SEQ +1 (x+1) of the first handshake packet sent by the Client. [Client brother, I am ready according to your disconnection request, I am going to disconnect.]

4. After receiving a FIN packet that is disconnected from the Server, the Client replies an ACK packet. The ACK bit is 1 and Acknowledgement Number (ACK) is the SEQ +1 (Y +1) of the packet waved by the Server for the third time. In this case, the Client waits for 2MSL to ensure that the Server receives the fourth ACK packet. If the Server does not receive the ACK packet, it resends the FIN packet within 2MSL and waits for another 2MSL. Okay, I got it.

At this point, the TCP connection between the Client and Server is disconnected and the state is CLOSED.

Think about:

  • Why does it take four waves?

    Again, I understand at least 4 times.

    When the Server receives the first FIN packet from the Client, the Client stops sending data but can still receive data. The Server may not send all data to the Client. Therefore, the Server can Close immediately or send some data to the Client. The Server then sends a FIN packet to the Client to close the connection. Therefore, the Server sends ACK packets and FIN packets separately.


TCP packet capture analysis


After understanding the theory, tcpdump is used to capture packets and analyze the TCP three-way handshake, data transmission, and four-way wave. Find two machines to act as a server (10.246.100.61) and a client (10.246.131.47).

Run the sudo tcpdump -s -nn -i en0 port 8080 command on the server to listen for network data on port 8080 on the server

Start listener on server (MacOS Big Sur11.3.1) :

public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket = new ServerSocket(8080);
        while (true){
            Socket clientSocket = serverSocket.accept(); // If there is no client connection there will be blocked
            System.out.println("Received a client");
            while (true) {
                InputStream inputStream = clientSocket.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                String content = bufferedReader.readLine();
                if (content == null) {
                    clientSocket.close();
                    System.out.println("clientSocket.close();");
                    break;
                }
                System.out.println("The server receives a message:"+ content); }}}}Copy the code

Establish TCP communication and send data to the server on the client (MacOS Big Sur11.5.2) :

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket =null;
        try {
            socket =  new Socket("10.246.100.61".8080);
            String content = StringUtils.randomAlphanumeric(10);
            OutputStream outputStream = socket.getOutputStream();
            BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream));
            bufferedWriter.write(content); // Send a 10-byte string
            bufferedWriter.flush();
            bufferedWriter.write(content+content); // Send a 20-byte string
            bufferedWriter.flush();
            bufferedWriter.write(content+content+content);  // Send a 30-byte string
            bufferedWriter.flush();
            bufferedWriter.write(content+content+content+content);  // Send a 40-byte string
            bufferedWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch(IOException e) { e.printStackTrace(); }}}}Copy the code

1. The server starts the listening, and the client runs in debug mode. The packets monitored are as follows:

10:18:41.756843 IP 10.246.131.47.63912 > 10.246.100.61.8080: Flags [S], seq 1495498772, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 3619360037 ecr 0,sackOK,eol], Length 0 10:18:41.757370 IP 10.246.100.61.8080 > 10.246.131.47.63912: Flags [S.], seq 2016084851, ack 1495498773, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 2360293984 ecr 3619360037,sackOK,eol], Length 0 10:18:41.765520 IP 10.246.131.47.63912 > 10.246.100.61.8080: Flags [.], ack 2016084852, win 2058, options [nop,nop,TS val 3619360151 ecr 2360293984], Length 0 10:18:41.765662 IP 10.246.100.61.8080 > 10.246.131.47.63912: Flags [.], ack 1495498773, win 2058, options [nop,nop,TS val 2360293992 ecr 3619360151], Length 0 10:18:58.575970 IP 10.246.131.47.63912 > 10.246.100.61.8080: Flags [P.], seq 1495498773:1495498783, ack 2016084852, win 2058, options [nop,nop,TS val 3619376924 ecr 2360293992], Length 10: HTTP 10:18:58.576153 IP 10.246.100.61.8080 > 10.246.131.47.63912: Flags [.], ack 1495498783, win 2058, options [nop,nop,TS val 2360310774 ecr 3619376924], Length 0 10:19:02.545456 IP 10.246.131.47.63912 > 10.246.100.61.8080: Flags [P.], seq 1495498783:1495498803, ack 2016084852, win 2058, options [nop,nop,TS val 3619380793 ecr 2360310774], Length 20: HTTP 10:19:02.545660 IP 10.246.100.61.8080 > 10.246.131.47.63912: Flags [.], ack 1495498803, win 2058, options [nop,nop,TS val 2360314738 ecr 3619380793], Length 0 10:19:03.753664 IP 10.246.131.47.63912 > 10.246.100.61.8080: Flags [P.], seq 1495498803:1495498833, ack 2016084852, win 2058, options [nop,nop,TS val 3619382076 ecr 2360314738], Length 30: HTTP 10:19:03.753819 IP 10.246.100.61.8080 > 10.246.131.47.63912: Flags [.], ack 1495498833, win 2057, options [nop,nop,TS val 2360315943 ecr 3619382076], Length 0 10:19:05.307899 IP 10.246.131.47.63912 > 10.246.100.61.8080: Flags [P.], seq 1495498833:1495498873, ack 2016084852, win 2058, options [nop,nop,TS val 3619383518 ecr 2360315943], Length 40: HTTP 10:19:05.308117 IP 10.246.100.61.8080 > 10.246.131.47.63912: Flags [.], ack 1495498873, win 2057, options [nop,nop,TS val 2360317496 ecr 3619383518], Length 0 10:19:10.325498 IP 10.246.131.47.63912 > 10.246.100.61.8080: Flags [F.], seq 1495498873, ack 2016084852, win 2058, options [nop,nop,TS val 3619388584 ecr 2360317496], Length 0 10:19:10.325731 IP 10.246.100.61.8080 > 10.246.131.47.63912: Flags [.], ack 1495498874, win 2057, options [nop,nop,TS val 2360322498 ecr 3619388584], Length 0 10:19:10.332732 IP 10.246.100.61.8080 > 10.246.131.47.63912: Flags [F.], seq 2016084852, ack 1495498874, win 2057, options [nop,nop,TS val 2360322505 ecr 3619388584], IP 10.246.131.47.63912 > 10.246.100.61.8080: Flags [.], ack 2016084853, win 2058, options [nop,nop,TS val 3619388641 ecr 2360322505], length 0Copy the code

Socket = new socket (“192.168.2.202”, 8080); After that, tcpdump listens to the packets in line 1-4 and can find that line 1-3 is the process of the client and server establishing a connection by three handshakes:

  1. For the first handshake, the client seq is 1495498772.
  2. During the second handshake, the ack returned by the server is seQ +1=1495498773 from the first client and 2016084851 from the server.
  3. During the third handshake, the ack returned by the client is seQ +1=2016084852.

Wireshark is used to analyze the packets in line 4, and you can see that the TCP Window Update flag is displayed. This indicates that the server adjusts the TCP Window to 131712 based on its processing capability, and you can find that Win in subsequent packets is changed to 131712.

The client then executes bufferedwriter.flush () each time; , the client sends data to the server and the server replies ack. In this code, the client sends data four times in total, and tcpdump also listens to four groups of packets that send data and ACK.

The last four lines are four waves.

  1. After sending data, the client sends the first wave packet to the server. The FIN flag bit is 1, SEQ =1495498873 (the end of the last packet during communication +1), ACK =2016084852 (the server seQ during handshake, The server is receiving data but not sending it.
  2. After receiving the FIN packet from the client, the server replies with an ACK packet with the ACK bit 1 (SEQ =1495498874). In this case, the server replies only an ACK packet, but does not send a FIN packet to the client.
  3. After processing the task in hand, the server sends a FIN packet to the client to disconnect the connection.
  4. After receiving the FIN packet from the server, the client replies with an ACk packet. After receiving the ACk packet, the server enters the CLOSE state. After 2MSL, the client will enter the CLOSE state and the connection will be officially disconnected.


2. The server starts the listening, and the client directly runs the program in run mode (no pause in the middle). The message monitored is as follows:

10:27:40.877203 IP 10.246.131.47.63941 > 10.246.100.61.8080: Flags [S], seq 1402389697, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1119685773 ecr 0,sackOK,eol], length 0
10:27:40.877672 IP 10.246.100.61.8080 > 10.246.131.47.63941: Flags [S.], seq 1063401628, ack 1402389698, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1726411899 ecr 1119685773,sackOK,eol], length 0
10:27:40.887556 IP 10.246.131.47.63941 > 10.246.100.61.8080: Flags [.], ack 1063401629, win 2058, options [nop,nop,TS val 1119685830 ecr 1726411899], length 0
10:27:40.887669 IP 10.246.100.61.8080 > 10.246.131.47.63941: Flags [.], ack 1402389698, win 2058, options [nop,nop,TS val 1726411909 ecr 1119685830], length 0
10:27:40.893232 IP 10.246.131.47.63941 > 10.246.100.61.8080: Flags [P.], seq 1402389698:1402389708, ack 1063401629, win 2058, options [nop,nop,TS val 1119685836 ecr 1726411899], length 10: HTTP
10:27:40.893310 IP 10.246.100.61.8080 > 10.246.131.47.63941: Flags [.], ack 1402389708, win 2058, options [nop,nop,TS val 1726411914 ecr 1119685836], length 0
10:27:40.894503 IP 10.246.131.47.63941 > 10.246.100.61.8080: Flags [FP.], seq 1402389708:1402389798, ack 1063401629, win 2058, options [nop,nop,TS val 1119685837 ecr 1726411899], length 90: HTTP
10:27:40.894541 IP 10.246.100.61.8080 > 10.246.131.47.63941: Flags [.], ack 1402389799, win 2057, options [nop,nop,TS val 1726411915 ecr 1119685837], length 0
10:27:40.895056 IP 10.246.100.61.8080 > 10.246.131.47.63941: Flags [F.], seq 1063401629, ack 1402389799, win 2057, options [nop,nop,TS val 1726411915 ecr 1119685837], length 0
10:27:40.901068 IP 10.246.131.47.63941 > 10.246.100.61.8080: Flags [.], ack 1063401630, win 2058, options [nop,nop,TS val 1119685842 ecr 1726411915], length 0
Copy the code

Lines 1 to 4 are the same as the previous captured packets. The first packet sent by the client (a string of 10 bytes) is the same as the previous captured packets. The length of the packet is 10 (length=10).

However, in line 7, the client clearly sends the second, third, and fourth data, but TCP is sent to the server through a TCP packet whose length=90, which is exactly the sum of the second, third, and fourth data (20+30+40=90). This is often referred to as sticky packet.

In addition, the FIN control is set to 1 when the client sends the packet in line 7, which means that the client disconnects the connection for four times after the last data packet is sent. (Client: “Send this message, I will disconnect with you”), such benefits the last time the client sends a message, the server ACK these two messages by the way to do the first two times of four waves to save the time to send two packets.


3. The server starts the listener, and the client directly runs the program in run mode, sending only 1500 bytes of data:

Client segment code:

public class Client { public static void main(String[] args) throws IOException { Socket socket =null; Try {socket = new socket ("10.246.100.61", 8080); String content = StringUtils.randomAlphanumeric(1500); OutputStream outputStream = socket.getOutputStream(); BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream)); bufferedWriter.write(content); bufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); }}}}Copy the code

Monitored packets:

18:07:15.126983 IP 10.246.131.47.65168 > 10.246.100.61.8080: Flags [S], seq 4127151943, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1726020163 ecr 0,sackOK,eol], length 0
18:07:15.127462 IP 10.246.100.61.8080 > 10.246.131.47.65168: Flags [S.], seq 1459700619, ack 4127151944, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 3332064821 ecr 1726020163,sackOK,eol], length 0
18:07:15.134597 IP 10.246.131.47.65168 > 10.246.100.61.8080: Flags [.], ack 1459700620, win 2058, options [nop,nop,TS val 1726020212 ecr 3332064821], length 0
18:07:15.134744 IP 10.246.100.61.8080 > 10.246.131.47.65168: Flags [.], ack 4127151944, win 2058, options [nop,nop,TS val 3332064828 ecr 1726020212], length 0

18:07:15.163846 IP 10.246.131.47.65168 > 10.246.100.61.8080: Flags [.], seq 4127151944:4127153392, ack 1459700620, win 2058, options [nop,nop,TS val 1726020239 ecr 3332064828], length 1448: HTTP
18:07:15.163856 IP 10.246.131.47.65168 > 10.246.100.61.8080: Flags [P.], seq 4127153392:4127153444, ack 1459700620, win 2058, options [nop,nop,TS val 1726020239 ecr 3332064828], length 52: HTTP
18:07:15.163958 IP 10.246.100.61.8080 > 10.246.131.47.65168: Flags [.], ack 4127153444, win 2035, options [nop,nop,TS val 3332064857 ecr 1726020239], length 0

18:07:15.165164 IP 10.246.131.47.65168 > 10.246.100.61.8080: Flags [F.], seq 4127153444, ack 1459700620, win 2058, options [nop,nop,TS val 1726020240 ecr 3332064828], length 0
18:07:15.165233 IP 10.246.100.61.8080 > 10.246.131.47.65168: Flags [.], ack 4127153445, win 2048, options [nop,nop,TS val 3332064858 ecr 1726020240], length 0
18:07:15.166150 IP 10.246.100.61.8080 > 10.246.131.47.65168: Flags [F.], seq 1459700620, ack 4127153445, win 2048, options [nop,nop,TS val 3332064858 ecr 1726020240], length 0
18:07:15.171678 IP 10.246.131.47.65168 > 10.246.100.61.8080: Flags [.], ack 1459700621, win 2058, options [nop,nop,TS val 1726020247 ecr 3332064858], length 0
Copy the code

As mentioned earlier in the article, the maximum MSS is 1460, that is, TCP packets can carry up to 1460 bytes of data, and 1500 bytes of data are sent. As expected, two TCP packets are split and sent respectively. The first one sends 1448 bytes of data (length=1448). The second packet sends the remaining 52 bytes of data (length=42). The data is too large to split into two packets is understandable, but why is 1550 bytes of data split into 1448 bytes +52 bytes instead of 1460+40 bytes? Wireshark analysis shows that the optional part takes up 12 bytes (including two NOP flags of one byte each and Timestamps of 10 bytes), so the maximum amount of data that can be carried is 1460-12=1448 bytes:

Above message can also see that the client is at the same time, line 6, 5 the two message sent, sent the first message after not to wait for an ack from the server, and then followed by the second message sent, the actual cases, the client sends data don’t have to wait to receive an ack packet on the service side to send, The client sends multiple packets at a time. After receiving the packets, the server ack the last received packets. For example, the client sends three packets with seQ of 1, 2, and 3 respectively. If the server receives only the packet with SEQ of 1, it replies with ACK of 2 (it indicates that all packets before 2 are received. Please send the packet with SEQ of 2). If the server receives packets with SEQ 1 or 2, the ack of the reply packet is 3 (it indicates that all packets before 3 are received. Please send the packet with SEQ 3). If the server receives all the packets within a short period of time, it replies with an ACK of 4 (indicating that all the packets before 4 were received, please send the packets with a SEQ of 4).

TCP communication process may encounter a lot of problems, there are many complex scenarios, here is just a simple packet analysis, if there is wrong, I hope to include to correct.