如何在 Node.js 中强制重置套接字?

2024-01-09

我从 Node.js 应用程序收到“read ECONNRESET”错误(可能是客户端或服务器连接,我不确定)。

作为修复这些问题的一部分,我想做一些本地测试,最好为其设置自动化测试。我想编写一个节点客户端和服务器,在连接建立后立即对其进行硬重置,以便我可以对此进行测试。

设置服务器/客户端很容易,但我不确定如何强制重置连接以重现我在这里看到的问题。节点套接字文档 https://nodejs.org/api/net.html#net_class_net_socket不要在任何地方提到重置

有任何想法吗?


2023 年更新

链接的问题已合并。您现在可以使用以下命令发送 RST 包socket.resetAndDestroy().

const net = require('net');

const socket = new net.Socket();

socket.connect(8000, "127.0.0.1", () => {
    socket.write(
        'GET / HTTP/1.1\n' +
        'Host: example.com\n\n'
    );
    setTimeout(() => socket.resetAndDestroy(), 0);
});

旧答案

据我所知,没有完美的解决方案,但我找到了两种选择,并且提交了针对 Node 的错误以添加适当的支持 https://github.com/nodejs/node/issues/27428.

对于我的问题(启动 HTTP 请求,然后 RST 套接字),我找到了两种解决方案:

在接收数据包之前销毁套接字

const net = require('net');

const socket = new net.Socket();
socket.connect(8000, "127.0.0.1", () => {
    socket.write(
        'GET / HTTP/1.1\n' +
        'Host: example.com\n\n'
    );
    setTimeout(() => socket.destroy(), 0);
});

如果您知道您将在此连接上收到数据包,您可以destroy()事先立即连接插座。这不会发送 RST,但会发送 RST 以响应未来的数据包。

为此,您需要在消息写入后、响应到达之前竞相销毁套接字。对于本地连接来说,这尤其棘手 -setTimeout(() => socket.destroy(), 0)是我找到的最可靠的解决方案,但是 YMMV,而且它肯定不能保证。我预计write()回调可以更可靠地工作,但似乎并非如此。

使用另一种语言(即Python)

对我来说,我现在又转而使用 Python 进行测试,因为它可以直接控制这一点。在Python中发送RST数据包:

import socket
import time
import struct

TCP_IP = '127.0.0.1'
TCP_PORT = 8000

# Connect to the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
s.connect((TCP_IP, TCP_PORT))

# Start an HTTP request
s.send("GET / HTTP/1.1\r\n\
Host: example.com\r\n\
\r\n")
time.sleep(0.1)

# RST the socket without reading the response
# See https://stackoverflow.com/a/6440364/68051 for context
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
s.close()

希望 Node 团队尽快考虑添加类似的支持(请参阅https://github.com/nodejs/node/issues/27428 https://github.com/nodejs/node/issues/27428),但同时上述内容可能会有所帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Node.js 中强制重置套接字? 的相关文章

随机推荐