关于服务器中出现close_wait状态占有端口问题
今天学习过程中发现了自己编写的服务器多次运行后,该端口的网络状态变成close_wait,导致服务器无法使用该端口。
首先,要理解出现的步骤,
在TCP状态图中,当服务器接收到对端的关闭FIN请求后返回ACK确认请求然后服务端进入close_wait,当长时间
处于close_wait状态,说明服务端并未主动进行关闭。主要问题就是你的代码并未正确处理主动关闭连接。可能是程序
正处于读写,而在读写结束后又未正确的进行close连接,导致未能进入last_ack状态。
综上所述,是代码中close的问题。
//贴一个简单的echo服务器
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #define PORT 10002 int main(){ //缓存区 char buf[BUFSIZ]; int listenfd; int port = PORT; listenfd = socket(AF_INET, SOCK_STREAM, 0); //消除bind "address already in use" int flag = 1; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons((unsigned int)port); if(bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1){ return -1; } listen(listenfd, 1024); struct sockaddr_in client; memset(&client, 0, sizeof(client)); socklen_t client_len = sizeof(client); int accept_fd = 0; accept_fd = accept(listenfd, (struct sockaddr*)&client, &client_len); if(accept_fd < 0){ printf("errno is %d\n", errno); } else{ printf("ip : %s", inet_ntoa(client.sin_addr)); printf("port: %d", ntohs(client.sin_port)); int pipefd[2]; if(pipe(pipefd) == -1){ perror("pipe errno! \n"); } ssize_t ret = splice(accept_fd, NULL, pipefd[1], NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE); if((ret) == -1){ perror("splice errno! \n"); } ssize_t ret1 = splice(pipefd[0], NULL, accept_fd, NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE); if((ret1) == -1){ perror("splice errno! \n"); } } close(accept_fd); close(listenfd); return 0; }