当tcp客户端与我的TCP服务器建立tcp连接时,在发送几个数据包之后,我想在这个TCP连接上进行硬/中断关闭,如何在linux C中进行?
这里的硬/中止关闭意味着tcp服务器会立即向客户端发送RST。完全没有FIN / ACK。
谢谢!
答案 0 :(得分:5)
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。