linux netcat的问题,请求帮助
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux netcat的问题,请求帮助相关的知识,希望对你有一定的参考价值。
参考技术A http://my.oschina.net/eechen/blog/206444yum install nc
二进制文件:
http://mirror.centos.org/centos/6/os/x86_64/Packages/nc-1.84-22.el6.x86_64.rpm
源代码:
http://vault.centos.org/6.4/os/Source/SPackages/nc-1.84-22.el6.src.rpm
Ubuntu上默认安装的是netcat-openbsd,而不是经典的netcat-traditional.
网上例子很多都是以netcat-traditional为例.
sudo apt-get -y install netcat-traditional
设置默认的nc,选择/bin/nc.traditional:
sudo update-alternatives --config nc
使netcat在断开连接后丢弃所有字节
【中文标题】使netcat在断开连接后丢弃所有字节【英文标题】:Make netcat discard all bytes after disconnect 【发布时间】:2017-09-19 10:35:12 【问题描述】:我使用 netcat 通过 bash 运行一个小型开发网络服务器,它能够一次处理一个连接。
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
。
再次在终端 2 中运行 nc localhost 3000
(新连接)。
终端 2 立即显示 world\n
,即使在不存在连接时实际发送了 world\n
,这意味着作为第一个连接中的第二个响应行。
必需的行为:如果不存在连接,则忽略传递给 netcat 的所有字节。
可以使用netcat吗? (我更喜欢 netcat 这样的工具,因为它预装在所有机器上。)
【问题讨论】:
您能否详细说明您是如何在 netcat 和您的脚本之间进行交互的? 我问这个问题是因为 cf 我的编辑(行后) 您需要让您的 http 服务器程序生成您要运行的脚本,以便在断开连接时,当脚本将执行返回给父级时,输出将被丢弃。我相信nmap的ncat可以做到。或者您可以write your own webserver 控制 fds,并确保在客户端断开连接时刷新所有输出。 好吧,在 ubuntu 上默认安装了 python,并且您提供了一个极简的 Web 服务器实现,例如,为了提供文件,您只需执行python -m SimpleHTTPServer <port>
(变为 http.server
in python 3.x),这相当 @ 987654324@.
这点很好,谢谢。我正在玩ncat
,如果它不起作用,我将使用Python的简单HTTP服务器。
【参考方案1】:
好吧,作为一种解决方法,如果你可以这样做,而不是使用保持打开选项运行 ncat,只需在 while 循环中的每个连接之间重新生成它:
while true; do
#what you want to do with: ncat -l 3000
done
然后每次进程重生时,它会丢弃所有标准输入,然后你从下一个 i/o 重新开始下一个进程。
当然,如果重新生成 bash 脚本不方便,那么这可能意味着您没有使用正确的工具来完成这项工作。 (您也许可以解决使用 fifos 或使用临时 fds 的问题,但为了避免使用更适合该工作的语言编写脚本,这将是过度设计。
如果您还没有这样做,您是否尝试过从 netcat 运行脚本而不是相反?
ncat -kl 3000 -c ./script.sh
它将为每个连接生成脚本,并在该脚本上重定向标准输入/标准输出。然后当客户端断开连接时,脚本将被终止并且应该释放您的输入 fd。
实际上,如果您将文件作为 http 服务器提供服务,您可能需要查找:
ncat -lk 3000 --lua-exec httpd.lua
httpd.lua
offered with the ncat distribution
如果您想要一个简单的随处运行脚本在您的系统上执行某些操作,您可以编写一个小型 python 脚本。
它默认安装在 ubuntu(和许多其他系统)上,并且您提供了一个极简的 Web 服务器实现,例如用于提供您刚刚执行的文件:
python -m SimpleHTTPServer <port>
cf SimpleHTTPServer for py2
或http.server
在py3中
它是easy to customize,可以满足您的独特需求,并为您提供对套接字和文件描述符的完全控制。
【讨论】:
如果我使用循环,如果没有监听套接字,随着时间的推移,这将不起作用。如果我错了,请纠正我。 什么意思? 确实,尽管重生之间的时间很短,但它仍在发生。虽然如果您在那个 短 时间内建立连接的可能性很小,那么您可能会认为您使用了错误的工具来完成任务,这可能是一个迹象你应该用比 shell 更灵活的语言来写一些东西(比如 python、ruby、lua……)。您可以编写整个 netcat+脚本,也可以编写一个 netcat 替代品,它会在下一次连接之前删除标准输出。 虽然,在 netcat 的 nmap 版本中,正如我在编辑中展示的那样,有一种方法可以生成一个 stdin/stdout 将是本地的进程,所以它很可能会回答您的请求. 其实nmap已经接手了netcat的开发,相信应该是官方的源码树☺【参考方案2】:坚持“到处运行”脚本的需要,您可以尝试逐行处理输入并检测是否存在与 netstat 的 ESTABLISHED 连接:
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 保持其标准输入打开,即使不存在连接:
mkfifo test
nc -kl < test
# then in a different shell
for a in 0..5; do echo hi > test; done
for
不会阻塞,因此 netcat 正在积极读取标准输入但正在缓冲它(我看不到关闭缓冲的选项)。这意味着除了查看网络状态外,您无法真正区分 netcat 有无活动连接。 netstat 是获取此状态的众多方法之一。
【讨论】:
我喜欢您的解决方案,因为它会在连接丢失后立即停止发送。不幸的是,它太慢了,因为我需要测试每个字节的连接,即使这样它也不是 100% 可靠,因为客户端关闭连接后发送的最后一个字节将通过以下连接。以上是关于linux netcat的问题,请求帮助的主要内容,如果未能解决你的问题,请参考以下文章