C 与苏林格·韩元合上';不要发送RST

C 与苏林格·韩元合上';不要发送RST,c,linux,sockets,tcp,C,Linux,Sockets,Tcp,我正试图在连接上强制TCP重置。 建议的方法是将SO_LINGER设置为0并关闭调用() 我正是这么做的,但这种联系仍保持在既定状态。 插座在非阻塞模式下运行。操作系统是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

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

我正是这么做的,但这种联系仍保持在既定状态。 插座在非阻塞模式下运行。操作系统是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套接字描述符时,我发现子进程已经从父进程打开了文件描述符(即使父进程已经没有打开)

解决方案是请求在forked进程中关闭文件描述符(就在
accept()
之后)


在您的情况下,在调用
close
后,您将无法再发送和接收数据。此外,在
close
调用之后,仅当套接字描述符的引用计数器变为0时,才会发送RST。然后连接进入关闭状态,接收和发送缓冲区中的数据被丢弃。
答案可能在于如何分叉流程(正如EJP在评论中提到的)。调用
fork
后,似乎没有关闭父进程中接受的套接字。因此,套接字引用计数器为非零,并且在
关闭后不会立即出现RST


Stevens在UNIX网络编程中很好地描述了这种情况。

您是否已经完成了一个过程
close()
只会在最后一次关闭时执行它所执行的操作(如果有叉子)。感谢您为我指明了正确的方向。问题不是立即出现的-文件描述符是通过调用system()泄漏的(实际上它是一个fork)。设置正确的文件描述符选项解决了该问题。
fcntl(server->connection_socket, F_SETFD, FD_CLOEXEC)