我正在使用嵌入式Linux单元,这是我的情况:
我使用我的计算机(Ubuntu 16.04 机器)远程登录到发出reboot
命令的设备,然后设备成功重新启动。
问题来了,我希望Connection closed by foreign host.
当设备自行关闭时,telnet 会返回并提示。但它并没有及时,相反,它Connection closed by foreign host.
仅在之后提示
我在电脑上按回车键 和
设备启动后/启动期间
当我从我的计算机上对其他设备执行相同的操作时,就没有这样的问题。
这是为什么?这是telnet的问题、我的电脑的问题还是嵌入式单元的问题?我该如何修复它?
答案1
最有可能的是,您的客户端系统(您运行 telnet 的系统)没有全局启用 TCP keepalive(而且可以说不应该),并且嵌入式系统没有正常关闭连接。
这是网络服务的一个常见问题,网络服务为每个用户会话生成单独的进程,然后在主进程关闭时不终止它们(但另一方面,您可以重新启动服务进行升级,而无需影响连接的用户,这就是他们首先这样做的原因)。
答案2
您可以通过在套接字上应用一些选项来仅为您的 telnet 连接启用 keepalive。您可以简单地使用现有的库,而不是编码并重新编译程序libkeepalive。
下载源 tar 文件 ,libkeepalive-0.3.tar.gz
并使用命令 编译库make
。
tar xvzf libkeepalive-0.3.tar.gz
cd libkeepalive-0.3
make
您将拥有一个文件libkeepalive.so
。您现在可以在预加载库的情况下运行 telnet。它将对该socket()
功能进行适当的更改。您可以在环境中设置 3 个值,例如全局 keepalive。例如,
LD_PRELOAD=$PWD/libkeepalive.so \
KEEPCNT=2 KEEPIDLE=2 KEEPINTVL=4 telnet hostname
现在,当远程停止响应 keepalive 数据包时,telnet 命令将退出并显示Connection closed by foreign host.
请参阅README
源中的文件:
KEEPCNT <=> net.ipv4.tcp_keepalive_probes
KEEPIDLE <=> net.ipv4.tcp_keepalive_time
KEEPINTVL <=> net.ipv4.tcp_keepalive_intvl
在 KEEPIDLE 秒之后,将每隔 KEEPINTVL 秒发送一个保活数据包。 KEEPCNT 数据包没有回复后,断开连接。