在 TCP/IP 套接字连接中发送重置

Posted

技术标签:

【中文标题】在 TCP/IP 套接字连接中发送重置【英文标题】:Sending a reset in TCP/IP Socket connection 【发布时间】:2011-09-20 08:28:57 【问题描述】:

我正在使用 python 的 socket.py 来创建到 ftp 服务器的连接。现在我想重置连接(发送一个 RST 标志)并监听 ftp-server 的响应。 (仅供参考,使用 socket.send('','R') 不起作用,因为操作系统发送的是 FIN 标志而不是 RST。)

【问题讨论】:

为什么要重置连接? 复制恶意ftpclient 相关:resetting a TCP connection from the server side 【参考方案1】:

打开 SO_LINGER 套接字选项并将逗留时间设置为 0 秒。这将导致 TCP 在连接关闭时中止连接,刷新数据并发送 RST。请参阅 UNP 中的第 7.5 节和示例 15.21。

在python中:

def client(host, port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
    s.connect((host, port))
    l_onoff = 1                                                                                                                                                           
    l_linger = 0                                                                                                                                                          
    s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,                                                                                                                     
                 struct.pack('ii', l_onoff, l_linger))
    # send data here
    s.close()

【讨论】:

它会导致 TCP 在关闭时中止连接,丢弃任何未决数据,并发送 RST。 对于那些好奇的人来说,这里只是一些更多信息:时间为 0 秒的 SO_LINGER 意味着 TCP 堆栈不会在 close() 上“徘徊”:它将丢弃任何未发送的数据并发送一个RST 而不是 FIN。欲了解更多信息,请阅读 this 和 this。 请注意,如果您在 Microsoft Windows 环境中使用此代码,则需要将调用 struct.pack() 中的 'ii' 替换为 'hh'。 Windows 在 struct linger 中使用 short,而 Linux 使用 ints。【参考方案2】:

如果您想通过连接实现自己的行为,我认为您应该尝试使用Scapy。这是一个非常有用的库/工具。它可以让您使用 IP/TCP/UDP/ICMP 包。

【讨论】:

【参考方案3】:

要在 TCP 连接上发送 RST,请将 SO_LINGER 选项设置为 true 并设置零超时,然后关闭套接字。这将重置连接。我不知道如何在 Python 中做到这一点,也不知道你是否可以做到。

【讨论】:

以上是关于在 TCP/IP 套接字连接中发送重置的主要内容,如果未能解决你的问题,请参考以下文章

TCP/IP网络编程:07优雅地断开套接字连接

Java TCP/IP Socket深入剖析socket——TCP套接字的生命周期

在 Windows 7 64 位上使用 TCP/IP 套接字发送/接收结构

Linux 网络编程详解九

Matlab TCP/IP 服务器套接字多连接

套接字实现Tcp服务器