Насколько я могу судить, идеального решения для этого не существует, но я нашел два варианта для этого и подал ошибку в Node, чтобы добавить надлежащую поддержку .
Для моей проблемы (запустите 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 для тестирования, так как он имеет прямой контроль над этим.Чтобы отправить пакет RST в Python:
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),, но выше может быть полезно в это время.