In Linux backend service network communication development, you may encounter situations with CLOSE_WAIT. The causes of the TCP CLOSE_WAIT state are numerous, but ultimately, it is due to the passive closing party not closing the socket connection. This article primarily uses a simple example with tools like TCPDUMP and Wireshark to simulate a CLOSE_WAIT situation, focusing mainly on explaining the underlying principles of this issue.

â1 Establishing a Listening Port on the CentOS Server: Understanding TCP CLOSE_WAITâ
In the virtual machine CentOS7 server (192.168.1.178), as shown in the figure above, open a terminal interface, and then use the following simple server program to establish a listening service on port 8000 (PID:5325).
1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 | /** * @FileName server_socket.c * @Describe A simple example for creating a listen as a server in linux system. * @Author vfhky 2016-02-26 18:45 * @Compile gcc server_socket.c -o server_socket */#include #include #include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include int main( int argc, char **argv ){ int server_sockfd; int client_sockfd; int len; int llOpt = 1; struct sockaddr_in my_addr; struct sockaddr_in remote_addr; int sin_size; char bufBUFSIZ; memset( &my_addr, 0, sizeof(my_addr) ); my_addr.sin_family = AF_INET; my_addr.sin_addr.s_addr = INADDR_ANY; my_addr.sin_port = htons(8000); if( ( server_sockfd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) { perror(âsocketâ); return 1; } if( setsockopt( server_sockfd, SOL_SOCKET, SO_REUSEADDR, &llOpt, sizeof(llOpt) ) ) { close(server_sockfd); return errno; } if( bind( server_sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr) ) < 0 ) { perror( âbindâ ); return 1; } listen( server_sockfd, 5 ); sin_size = sizeof( struct sockaddr_in ); printf( âSocket server begin to recieve connectiong from client.\nâ ); while(1) { if( ( client_sockfd = accept( server_sockfd, (struct sockaddr *)&remote_addr, &sin_size ) ) < 0 ) { perror( âacceptâ ); return 1; } //Print the ip address and port of client. printf( âAccept client%s:%u.\nâ, inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port) ); memset( buf, 0x00, BUFSIZ ); while( ( len = recv( client_sockfd ,buf, BUFSIZ, 0) ) > 0 ) { buflen=â\0âČ; printf( âMessage from client=%s\nâ, buf ); } close( client_sockfd ); } close( server_sockfd ); return 0;} |
---|
Use the netstat Command in Linux to Check the Status of TCP Services, Including TCP CLOSE_WAIT
Create a new shell script netstat.sh containing only one effective command. Executing this script will allow you to see the serverâs listening effect:

3 Using the telnet command in Linux to create a client
Open another Linux terminal interface, then enter the command to establish a TCP connection with the server as a client. Upon executing the script, you can see that the TCP communication between the Linux client (PID:5331) and the server (PID:5325) has successfully been established, as shown in the diagram below:

In Windows, use the telnet command to create a client
Open a PowerShell terminal interface in Windows, then enter the command to establish a TCP connection with the Linux server as a client.
At this point, when the script is executed, you can see that the TCP communication between the Windows client (port: 52552) and the server (PID: 5325) has established a connection, as shown in the figure below:

5 Using the tcpdump tool to capture packets in Linux
Open another Linux terminal interface, then enter a command to capture packets (with the aim of obtaining the data packets of the TCP connection established by the Windows client using telnet). When the Windows client initiates the âthree-way handshakeâ in Section 4, the following data was obtained:
The effect is as shown in the figure below:

6 Using Wireshark for Packet Capture in Windows
In Windows, after establishing a TCP link with the Linux server using a command (i.e., the operation in section 4 above), begin using Wireshark for packet capture starting with the Windows clientâs TCP port number 52552.
Manually close the Windows telnet terminal interface created in Section 4, then the packet capture in Wireshark is shown in the following figure:

At the same time, through the netstat.sh script in Linux, it was discovered that the TCP connection just established has changed its status.

Similarly, the tcpdump packet capture situation in Section 4 is as follows:
The effect is shown in the figure below:
