linux 带有epoll的单线程HTTP服务器无法接受并发连接并导致出现许多CLOSE_WAIT套接字

b4wnujal  于 2022-12-03  发布在  Linux
关注(0)|答案(1)|浏览(234)

我写了一个简单的单线程HTTP服务器,用epoll处理事件。服务器在正常的连接流中工作得很好,但是当并发连接增长时,许多套接字甚至在接受函数接受之前就进入CLOSE_WAIT状态。这种行为的原因是什么?
ss命令输出。

$ ss -n4tp '( dport = :9000 or sport = :9000 )'
State      Recv-Q Send-Q Local Address:Port Peer Address:Port Process
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:53782       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:49254       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:48408       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:55474       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:58076       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:52460       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:57912       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:52566       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:54044       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:52466       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:51688       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:55336       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:49494       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:56780       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:46982       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:54924       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:52552       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:56716       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:50430       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:49630       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:49436       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:52026       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:57966       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:48524       
CLOSE-WAIT 65     0          127.0.0.1:9000    127.0.0.1:52196

lsof命令输出。

$ lsof -a -p $(pidof Server)
COMMAND    PID   USER   FD      TYPE  DEVICE SIZE/OFF     NODE NAME
Server     179032 Server  cwd       DIR   259,7     4096 22158993 /run/media/Server/Free/Projects/Server/cmake-build-release
Server     179032 Server  rtd       DIR   259,6     4096        2 /
Server     179032 Server  txt       REG   259,7   141328 22164437 /run/media/Server/Free/Projects/Server/cmake-build-release/Server
Server     179032 Server  mem       REG   259,6  1953472  9972375 /usr/lib/libc.so.6
Server     179032 Server  mem       REG   259,6 19198496  9981664 /usr/lib/libstdc++.so.6.0.30
Server     179032 Server  mem       REG   259,6   571848  9966244 /usr/lib/libgcc_s.so.1
Server     179032 Server  mem       REG   259,6   944600  9978549 /usr/lib/libm.so.6
Server     179032 Server  mem       REG   259,6   231416 10017681 /usr/lib/libtbb.so.12.5
Server     179032 Server  mem       REG   259,6   216184  9971409 /usr/lib/ld-linux-x86-64.so.2
Server     179032 Server    0u      CHR   136,8      0t0       11 /dev/pts/8
Server     179032 Server    1u      CHR   136,8      0t0       11 /dev/pts/8
Server     179032 Server    2u      CHR   136,9      0t0       12 /dev/pts/9
Server     179032 Server    3u     IPv4 5423625      0t0      TCP *:cslistener (LISTEN)
Server     179032 Server    4u  a_inode    0,14        0     2107 [eventpoll:0,3]
mrphzbgm

mrphzbgm1#

在CLOSE-WAIT状态下,套接字的本地端已经关闭了它的连接端,但是远程端(在本例中是客户端)还没有关闭它的连接端。
在完成之后,您可以尝试在套接字的服务器端调用close函数来正确关闭连接。此外,您可以在套接字上调用shutdown函数来阻止它接收更多的数据,这可能有助于防止CLOSE-WAIT状态的发生。
下面是一个示例:

int result = shutdown(socket_fd, SHUT_RDWR);
if (result == -1) {
  // handle error
}
result = close(socket_fd);
if (result == -1) {
  // handle error
}

您还应该确保正确处理调用这些函数时可能发生的任何错误。

相关问题