linux netcat的问题,请求帮助

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux netcat的问题,请求帮助相关的知识,希望对你有一定的参考价值。

参考技术A http://my.oschina.net/eechen/blog/206444

yum 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的问题,请求帮助的主要内容,如果未能解决你的问题,请参考以下文章

Netcat详解

netcat,nmap常用例子

Linux centos6.5系统下升级gcc4.8.2时,编译gcc时出现错误,请求帮助

Linux下80端口转发,请帮助

linux怎么安装netcat

Netcat 问题重新连接