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

时间:2013-06-02 23:54:37

标签: c tcp network-programming

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

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

谢谢!

2 个答案:

答案 0 :(得分:5)

来自Socket man page

  

SO_LINGER       设置或获取SO_LINGER选项。这个论点是一个挥之不去的结构。

struct linger {
    int l_onoff;    /* linger active */
    int l_linger;   /* how many seconds to linger for */
};
  

启用后,关闭(2)或关闭(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相同。

答案 1 :(得分:2)

您应该使用超时0设置SO_LINGER套接字选项并调用close()。如果有任何未决数据要发送,则会丢失并发送RST而不是FIN。

参考:http://alas.matf.bg.ac.rs/manuals/lspe/snode=105.html