断开连接后使netcat丢弃所有字节
Make netcat discard all bytes after disconnect
我通过 bash 使用 netcat 运行 一个微型开发网络服务器,它能够一次处理一个连接。
Netcat 启动如下(-k
使其在多个连接中存活):
nc -kl 3000
bash 脚本处理由 netcat 接收的浏览器请求,并构建响应,该响应通过同一 netcat 实例发送回浏览器。
一切都按预期工作,但有时,浏览器无法获得它请求的文件。我的怀疑:如果在响应完全发送之前关闭连接,则响应的其余部分将作为对以下请求的响应发送(当然,它不属于)。
证明
- 终端 1(服务器):
nc -kl 3000
- 终端2(模拟浏览器):
nc localhost 3000
- 在终端 1 中输入
hello\n
。
- 2 号航站楼打印
hello\n
。
- 在终端2按Ctrl+C结束连接。
- 在终端 1 中输入
world\n
。
- 运行
nc localhost 3000
再次在终端 2(新连接)。
- 终端 2 立即显示
world\n
,即使 world\n
实际上是在不存在连接时发送的,这意味着第一个连接中的第二个响应行。
要求的行为:如果不存在连接,则忽略传递给 netcat 的所有字节。
是否可以使用netcat? (我更喜欢像 netcat 这样的工具,因为它预装在所有机器上。)
嗯,作为一种解决方法,如果你能做到这一点,而不是 运行ning ncat 使用保持打开选项,只需在 while 循环中的每个连接之间重新生成它:
while true; do
#what you want to do with: ncat -l 3000
done
然后每次进程重新生成时,它会丢弃所有标准输入,然后您从下一个 i/o 开始下一个进程。
当然,如果重新生成您的 bash 脚本不方便,那么这可能意味着您没有使用正确的工具来完成这项工作。 (您也许可以解决使用 fifos 或使用临时 fds 的问题,但为了避免使用更适合该工作的语言编写脚本,这会过度设计)。
如果您还没有这样做,您是否尝试过从 netcat 中 运行ning 脚本而不是相反?
ncat -kl 3000 -c ./script.sh
它将为每个连接生成脚本,并在该连接上重定向 stdin/stdout。然后当客户端断开连接时,脚本将被终止并且应该释放你的输入fd。
实际上,如果您将文件作为 HTTP 服务器提供,您可能需要查找:
ncat -lk 3000 --lua-exec httpd.lua
与 httpd.lua
offered with the ncat distribution
如果您想要一个简单的 运行 anywhere 脚本在您的系统上执行某些操作,您可以编写一个小的 python 脚本。
它默认安装在 ubuntu(以及许多其他系统)上,并且您提供了一个极简主义的 Web 服务器实现,例如用于提供您刚刚执行的文件:
python -m SimpleHTTPServer <port>
- cf SimpleHTTPServer for py2
- 或
http.server
在 py3
它 easy to customize 更适合您的独特需求,并且可以让您完全控制套接字和文件描述符。
坚持需要 "run everywhere" 脚本,您可以尝试逐行处理输入并检测是否存在 ESTABLISHED 连接 netstat:
while read line; do
netstat -an | grep 3000 | grep -q ESTABLISHED;
ret=$?;
if [ "$ret" == "0" ]; then
echo $line;
else
# this output is just for fun, and can be removed
echo "not sending $line" >&2;
fi;
done | nc -kl 3000
这将有基于线路的限制,如果连接在 netstat 调用后立即关闭,仍然可能错误地向 netcat 发送数据。这两个 grep 调用应该确保您不会错误地检测到您自己的 grep。
我尝试寻找连接关闭时 netcat 返回的信号,但看不到任何暴露给 shell 的信号。
使用 fifo 可以证明 netcat 保持其 stdin 打开,即使在不存在连接时也是如此:
mkfifo test
nc -kl < test
# then in a different shell
for a in {0..5}; do echo hi > test; done
for
不会阻塞,因此 netcat 正在主动读取标准输入但对其进行缓冲(我看不到关闭缓冲的选项)。这意味着除了查看网络状态外,您无法真正区分 netcat 是否具有活动连接。 netstat 是获取此状态的众多方法之一。
我通过 bash 使用 netcat 运行 一个微型开发网络服务器,它能够一次处理一个连接。
Netcat 启动如下(-k
使其在多个连接中存活):
nc -kl 3000
bash 脚本处理由 netcat 接收的浏览器请求,并构建响应,该响应通过同一 netcat 实例发送回浏览器。
一切都按预期工作,但有时,浏览器无法获得它请求的文件。我的怀疑:如果在响应完全发送之前关闭连接,则响应的其余部分将作为对以下请求的响应发送(当然,它不属于)。
证明
- 终端 1(服务器):
nc -kl 3000
- 终端2(模拟浏览器):
nc localhost 3000
- 在终端 1 中输入
hello\n
。 - 2 号航站楼打印
hello\n
。 - 在终端2按Ctrl+C结束连接。
- 在终端 1 中输入
world\n
。 - 运行
nc localhost 3000
再次在终端 2(新连接)。 - 终端 2 立即显示
world\n
,即使world\n
实际上是在不存在连接时发送的,这意味着第一个连接中的第二个响应行。
要求的行为:如果不存在连接,则忽略传递给 netcat 的所有字节。
是否可以使用netcat? (我更喜欢像 netcat 这样的工具,因为它预装在所有机器上。)
嗯,作为一种解决方法,如果你能做到这一点,而不是 运行ning ncat 使用保持打开选项,只需在 while 循环中的每个连接之间重新生成它:
while true; do
#what you want to do with: ncat -l 3000
done
然后每次进程重新生成时,它会丢弃所有标准输入,然后您从下一个 i/o 开始下一个进程。
当然,如果重新生成您的 bash 脚本不方便,那么这可能意味着您没有使用正确的工具来完成这项工作。 (您也许可以解决使用 fifos 或使用临时 fds 的问题,但为了避免使用更适合该工作的语言编写脚本,这会过度设计)。
如果您还没有这样做,您是否尝试过从 netcat 中 运行ning 脚本而不是相反?
ncat -kl 3000 -c ./script.sh
它将为每个连接生成脚本,并在该连接上重定向 stdin/stdout。然后当客户端断开连接时,脚本将被终止并且应该释放你的输入fd。
实际上,如果您将文件作为 HTTP 服务器提供,您可能需要查找:
ncat -lk 3000 --lua-exec httpd.lua
与 httpd.lua
offered with the ncat distribution
如果您想要一个简单的 运行 anywhere 脚本在您的系统上执行某些操作,您可以编写一个小的 python 脚本。
它默认安装在 ubuntu(以及许多其他系统)上,并且您提供了一个极简主义的 Web 服务器实现,例如用于提供您刚刚执行的文件:
python -m SimpleHTTPServer <port>
- cf SimpleHTTPServer for py2
- 或
http.server
在 py3
它 easy to customize 更适合您的独特需求,并且可以让您完全控制套接字和文件描述符。
坚持需要 "run everywhere" 脚本,您可以尝试逐行处理输入并检测是否存在 ESTABLISHED 连接 netstat:
while read line; do
netstat -an | grep 3000 | grep -q ESTABLISHED;
ret=$?;
if [ "$ret" == "0" ]; then
echo $line;
else
# this output is just for fun, and can be removed
echo "not sending $line" >&2;
fi;
done | nc -kl 3000
这将有基于线路的限制,如果连接在 netstat 调用后立即关闭,仍然可能错误地向 netcat 发送数据。这两个 grep 调用应该确保您不会错误地检测到您自己的 grep。
我尝试寻找连接关闭时 netcat 返回的信号,但看不到任何暴露给 shell 的信号。
使用 fifo 可以证明 netcat 保持其 stdin 打开,即使在不存在连接时也是如此:
mkfifo test
nc -kl < test
# then in a different shell
for a in {0..5}; do echo hi > test; done
for
不会阻塞,因此 netcat 正在主动读取标准输入但对其进行缓冲(我看不到关闭缓冲的选项)。这意味着除了查看网络状态外,您无法真正区分 netcat 是否具有活动连接。 netstat 是获取此状态的众多方法之一。