在Linux上如何不正常地关闭TCP连接

12

有没有办法在Linux上以C/C++编程的方式不正常地关闭TCP连接?

为了进行测试,我想模拟这样一种情况:一个端点突然断电,而没有传输任何FIN和/或RST,也没有刷新任何缓冲区。


3
我重新打开了这个问题,因为它不是链接问题的副本。那个问题问如何生成 RST;而这个问题问如何根本不生成任何数据包。 - user253751
5
这里有一个可能的解决方案,使用iptables像防火墙一样完全阻止连接:https://unix.stackexchange.com/questions/136642/how-to-make-a-tcp-socket-time-out - user253751
我对此不是很了解,但如果您启动另一个进程并将其终止呢? - HolyBlackCat
1
@HolyBlackCat 内核知道它被杀死,会像进程“关闭”套接字一样做出反应(我认为通常意味着它会发送 RST)。 - user253751
2
@Quimby,下一个传入的数据包将会收到RST响应,这是未知传入数据包的通常情况。 - user253751
显示剩余6条评论
4个回答

2
如果您通过 socket(AF_INET, SOCK_STREAM, 0); 打开套接字,则无法预测地实现不优雅的关闭,即使杀死进程仍会让内核域控制关闭套接字。
您可以通过外部阻止对该套接字的网络访问(例如 ifdown, iptables),并从程序中调用它来解决这个问题。或者,您将不得不使用 socket(AF_INET, SOCK_RAW, 0); 实现自定义 TCP 代码,以便内核不会尝试优雅地关闭它(因为它甚至不知道它是一个 TCP 套接字)。

1

最简单的模拟连接“突然中断”的方法可能是阻止(丢弃)连接上的传入数据包。一个类似于netfilter的命令:

iptables -A INPUT -p tcp --dport $PORT -j DROP

将会执行此操作--使用连接的本地端口号替换$PORT。这不会阻塞出站数据包(如果您有保持活动或定期发送数据的需求,则可能会出现问题)。您可以使用以下方法完成此操作:

iptables -A OUTPUT -p tcp --sport $PORT -j DROP

在完成后,请务必删除这些过滤规则,否则它们会留下并引起问题。


0

我更喜欢对网络驱动程序中断处理进行操作。

Linux内核提供了一种将IRQ亲和性设置为特定CPU的方法,以便IRQ只能由这些CPU处理。通过将IRQ亲和性设置为空CPU集,您可以有效地禁用IRQ。

禁用irqbalance守护程序。然后检查您的NIC驱动程序使用哪些中断。

cat /proc/interrupts

然后禁止任何CPU处理nic中断:

echo 0 > /proc/irq/N/smp_affinity


0

你可以使用 unistd.h 库中的 close 函数来关闭与套接字相关联的文件描述符。然而,值得注意的是,该方法可能不会立即终止连接,因为底层 TCP 协议有其自己的机制来关闭连接,并且这些机制可能需要一些时间才能完成。


1
提问者特别想避免执行那些底层机制,他们想要模拟一个不优雅的断开连接(例如有人拔掉以太网电缆),而不是控制性地关闭连接。 - Jeremy Friesner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接