gpt4 book ai didi

带有 SO_LINGER 的 close() 不会发送 RST

转载 作者:可可西里 更新时间:2023-11-01 02:42:15 24 4
gpt4 key购买 nike

我试图在连接上强制重置 TCP。建议的方法是将 SO_LINGER 设置为 0 并调用 close()。

我正在这样做,但连接仍处于 ESTABLISHED 状态。套接字以非阻塞模式运行。操作系统是 Raspbian。

代码:

struct linger l;
l.l_onoff = 1;
l.l_linger = 0;

if (setsockopt(server->connection_socket, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) != 0) {
LOG_E(tcp, "setting SO_LINGER failed");
}

if (close(server->connection_socket) != 0) {
LOG_E(tcp, "closing socket failed");
}

server->connection_socket = 0;
LOG_I(tcp, "current TCP connection was closed");

Wireshark 跟踪也显示没有 RST。

应用程序的其他线程没有在该套接字上执行任何操作。

我不知道哪里出了问题,任何建议将不胜感激。


已解决

问题是文件描述符泄漏给通过 system() 调用创建的子项。事实上,当我使用 lsof -i tcp 列出所有 TCP 套接字描述符时,我发现子进程已经从父进程打开了文件描述符(即使父进程已经没有)。

解决方案是请求在 fork 进程中关闭文件描述符(紧接在 accept() 之后)。

fcntl(server->connection_socket, F_SETFD, FD_CLOEXEC)

最佳答案

在您的情况下,您在调用 close 后无法再发送和接收数据。此外,在 close 调用之后,仅当套接字描述符的引用计数器变为 0 时才会发送 RST。然后连接进入 CLOSED 状态,并且数据在接收和发送中缓冲区被丢弃。
答案可能在于你如何 fork 一个过程(正如 EJP 在评论中提到的那样)。您似乎在调用fork 后没有关闭父进程中已接受的套接字。所以套接字引用计数器不为零,并且在您的关闭之后没有立即执行 RST。
Stevens 在 UNIX 网络编程中很好地描述了这种情况。

关于带有 SO_LINGER 的 close() 不会发送 RST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41023657/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com