如何在TCP连接上进行硬/中断关闭?

mis*_*yes 4 c network-programming tcp

当一个tcp客户端与我的TCP服务器建立tcp连接时,在它发送几个数据包后,我想在这个TCP连接上做一个硬/中断关闭,如何在linux C中做到这一点?

这里的硬/中止关闭意味着tcp服务器将立即向客户端发送RST.完全没有FIN/ACK.

谢谢!

a.m*_*.m. 5

来自Socket手册页

SO_LINGER设置或获取SO_LINGER选项.争论是一种挥之不去的结构.

struct linger {
    int l_onoff;    /* linger active */
    int l_linger;   /* how many seconds to linger for */
};
Run Code Online (Sandbox Code Playgroud)

启用后,在成功发送套接字的所有排队消息或已达到延迟超时之前,不会返回close(2)或shutdown(2).否则,调用立即返回,并在后台完成关闭.当套接字作为exit(2)的一部分关闭时,它总是在后台中徘徊.

另一种设置:

setsockopt(...,SO_LINGER,...)的效果取决于linger结构中的值(传递给setsockopt()的第三个参数)是:

情况1:linger-> l_onoff为零(linger-> l_linger没有意义):这是默认值.

在close()上,在确保发送所有未发送的数据之后,底层堆栈会尝试正常关闭连接.在面向连接的协议(如TCP)的情况下,堆栈还确保对等方确认发送的数据.无论套接字是阻塞还是非阻塞,堆栈都会在后台执行上述正常关闭(在调用close()之后返回).

情况2:linger-> l_onoff非零并且linger-> l_linger为零:

close()立即返回.底层堆栈丢弃任何未发送的数据,并且在面向连接的协议(例如TCP)的情况下,向对等方发送RST(重置)(这被称为硬关闭或中止关闭).对等应用程序对read()/ recv()数据的所有后续尝试都将导致ECONNRESET.

情况3:linger-> l_onoff非零并且linger-> l_linger不为零:

close()将阻塞(如果是阻塞套接字)或使用EWOULDBLOCK失败(如果是非阻塞),直到正常关闭完成或者在linger-> l_linger中指定的时间过去(超时).在超时时,堆栈的行为与上面的情况2相同.