如何在 TCP 连接上进行硬/中止关闭? [英] how to make a hard/abortive close on a TCP connection?

查看:22
本文介绍了如何在 TCP 连接上进行硬/中止关闭?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

谢谢!

解决方案

来自 Socket 手册页

<块引用>

SO_LINGER设置或获取 SO_LINGER 选项.参数是一个逗留结构.

struct linger {诠释 l_onoff;/* 逗留活跃 */诠释 l_linger;/* 等待多少秒 */};

<块引用>

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

其他设置:

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

案例一: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 相同.

when a tcp client establishes a tcp connection with my TCP server, after it sends several packets, I want to make a hard/abortive close on this TCP connection, how to do it in linux C?

the hard/abortive close here means the tcp server will send a RST immediately to the client. No FIN/ACK at all.

thanks!

解决方案

From Socket man page

SO_LINGER Sets or gets the SO_LINGER option. The argument is a linger structure.

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

When enabled, a close(2) or shutdown(2) will not return until all queued messages for the socket have been successfully sent or the linger timeout has been reached. Otherwise, the call returns immediately and the closing is done in the background. When the socket is closed as part of exit(2), it always lingers in the background.

Another settings :

The effect of an setsockopt(..., SO_LINGER,...) depends on what the values in the linger structure (the third parameter passed to setsockopt()) are:

Case 1: linger->l_onoff is zero (linger->l_linger has no meaning): This is the default.

On close(), the underlying stack attempts to gracefully shutdown the connection after ensuring all unsent data is sent. In the case of connection-oriented protocols such as TCP, the stack also ensures that sent data is acknowledged by the peer. The stack will perform the above-mentioned graceful shutdown in the background (after the call to close() returns), regardless of whether the socket is blocking or non-blocking.

Case 2: linger->l_onoff is non-zero and linger->l_linger is zero:

A close() returns immediately. The underlying stack discards any unsent data, and, in the case of connection-oriented protocols such as TCP, sends a RST (reset) to the peer (this is termed a hard or abortive close). All subsequent attempts by the peer's application to read()/recv() data will result in an ECONNRESET.

Case 3: linger->l_onoff is non-zero and linger->l_linger is non-zero:

A close() will either block (if a blocking socket) or fail with EWOULDBLOCK (if non-blocking) until a graceful shutdown completes or the time specified in linger->l_linger elapses (time-out). Upon time-out the stack behaves as in case 2 above.

这篇关于如何在 TCP 连接上进行硬/中止关闭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆