我的应用程序中有一些死连接,如果客户端计算机死机,这些连接就会进入挂起状态。其中一个连接显示为
->192.168.1.214:49029 (ESTABLISHED)
有没有办法在不重新启动服务器的情况下从 Linux 命令行终止这些连接?
经过搜索,我找到了一个名为 的解决方案tcpkill
,但它对我不起作用,因为它永久阻止了 IP。
答案1
在 Linux 内核 >= 4.9 上,您可以使用ss
iproute2 中的命令和 key-K
ss -K dst 192.168.1.214 dport = 49029
内核必须在CONFIG_INET_DIAG_DESTROY
启用选项的情况下进行编译。
答案2
最初是从:http://rtomaszewski.blogspot.sk/2012/11/how-to-forcously-kill-builted-tcp.html
要“杀死”套接字,您必须发送 TCP 重置数据包。要发送它(并被另一方接受),您必须知道实际的 TCP 序列号。
1) 已经提到的tcpkill
方法通过被动地嗅探网络并等待该连接的有效数据包到达来获知SEQ号。然后它使用学习到的SEQ号向双方发送RSET数据包。但是,如果连接空闲/挂起并且没有数据流,它将不会执行任何操作并且将永远等待。
2) 另一种方法使用名为killcx
(链接到 Sourceforge)。它主动发送欺骗性的 SYN 数据包并从应答中学习 SEQ 号。然后它以与 相同的方式发送 RSET 数据包tcpkill
。
另一种方法(基于您想要实现的目标)是使用gdb
调试器附加到拥有此套接字/连接的进程并close()
代表其发出系统调用 - 详细信息请参见回答。
如果您只想处理挂起的连接(另一端已死),则有各种超时(例如 TCP keepalive),如果在系统上正确配置,则应自动关闭此类连接。
答案3
tcpkill
可能会为你做。在 Ubuntu 中它位于dsniff
软件包中。
就像是:
$ sudo tcpkill -i wlan0 host 192.168.1.214
(或其他tcpdump
类似的表达方式来杀死什么连接)。
答案4
您可以尝试使用iptables
REJECT
with --reject-with tcp-reset
,它会在匹配数据包时将 RST 发送到远程。