前言

  最近的一个项目由一台中央管理电脑和90台设备构成,设备采用arm+fpag+linux搭建,通过网络与中央管理器通讯。开发的过程中发现一个问题,因为中央管理电脑需要操作90台设备,调试起来很麻烦,总不能怀疑哪台有问题就将串口接到那台设备或者通过ssh到那台设备,一台还好,如果多台的话,那就麻烦啦!于是我尝试着优化下调试方法,因此才有了这篇博文,效果很理想,也很实用,和大家分享下。

解决方案

  我想到了几个解决方案,下面一一描述。总体来说,第一阶段我想先实现将设备的log输出实时传送到远程调试电脑上,第二阶段(如果有必要的话),再将设备所有接收到的消息和传出的消息传送到远程调试电脑上。下面的解决方案都是围绕第一阶段进行的,毕竟,不到万不得已,不会要去实现第二阶段。

方案一 修改设备端已有的代码

  修改设备上已经运行的代码,在log那做些处理,传送到远程调试电脑上

优点:

  • 没(容易想到? _

缺点:

  • 需要在设备程序里增加一些无关的代码
  • 新添加的代码是否会带来额外的问题

方案二 不修改设备代码,在外部做处理

优点:

  • 不需要添加一些无关的代码到设备程序
  • 没有新添加代码,不会带来额外的稳定性等问题
  • 简洁,特别是低耦合效果非常好
  • 同时可以用于其他项目上

缺点:

实现

  不修改设备代码,在外部做处理,怎么实现呢? 我想可以通过重定向来完成,最终我也确实是通过该方法实现的,效果非常理想!我采用的工具是nc,这个一般都默认自带了的,在arm上也自带安装了(也可以通过tcpserver来实现,它在ucspi-tcp包中,对应的官网,命令类似tcpserver 127.0.0.1 1234 stdbuf -o0 ./a.out,由于nc比它通用,所以我选择了nc)。实现步骤如下:

  1. 设备端创建一个有名管道,mkfifo pipe
  2. 设备端执行程序时,额外加一些命令,比如之前仅仅执行./a.out,现在执行nc -lk 1234 < pipe | ./a.out > pipe
  3. 在远程电脑上连接到设备即可实时显示了,比如执行nc 192.168.1.100 1234

举例:

假设设备的ip为192.168.1.100,我们采用1234端口作为log输出端口,要执行的程序为a.out
那么,设备端执行mkfifo pipe后,再执行nc -lk 1234 < pipe | stdbuf -o0 ./a.out > pipe启动要执行的程序,然后远程调试电脑上只需要执行nc 192.168.1.100 1234即可实时显示a.out的输出信息了

有几个要注意的地方
nc 使用了k选项,确保即使远程调试电脑断开调试了,监听继续保持
stdbuf -o0是为了防止a.out程序的输出被cache,导致远程调试电脑上看到的效果不是实时的

以上就实现了远程调试电脑实时打印设备上a.out程序的输出,如果我们期望远程调试电脑不仅能够接受设备的输出,还能够接收设备的输入,可以将a.out替换成/bin/bash _ 这时远程调试电脑敲下命令后即刻就可以拿到命令的输出。这种方式的更简单实现是采用nc的nc.traditional版本(默认为openbsd版本,没有-e选项,可能是为了安全考虑吧,具体怎么操作,google吧!)

最后再说一下远程调试电脑怎么同时获取90台设备输出的。我采用的方式是通过脚本实现,内容如下:

#!/bin/bash

for i in `seq 101 190`
do
    nc 192.168.8.$i 1234 -d | sed "s/\(.*\)/[192.168.8.$i] \1/g" &
done

while :
do
    sleep 1
done

这里只有-d选项需要说明下,由于我是放在后台,如果没有-d选项,会导致nc在后台stop。

nc更多操作说明参考这里
ncat的介绍ncat
ncat vs nc介绍参考这里

Ncat is meant to be a modern implementation of Netcat using Nmap’s mature networking libraries, combining the best features of the various Netcat derivatives into one new tool. While Ncat is an extremely versatile tool with many amazing new features, it is not quite 100% reverse-compatible with the original Netcat.

其他和nc有意思的技巧:

One of the best examples of a practical use of a named pipe...

From http://en.wikipedia.org/wiki/Netcat

Another useful behavior is using netcat as a proxy. Both ports and hosts can be redirected. Look at this example:

nc -l 12345 | nc www.google.com 80

Port 12345 represents the request This starts a nc server on port 12345 and all the connections get redirected to google.com:80. If a web browser makes a request to nc, the request will be sent to google but the response will not be sent to the web browser. That is because pipes are unidirectional. This can be worked around with a named pipe to redirect the input and output.

nc.traditional相关内容:

sudo apt-get install netcat-traditional # netcat-openbsd
nc.traditional server 6767 -e myscript.sh
nc.traditional -l -p 1234 -e /bin//bash
nc.openbsd -l 6767

(note the subtle differences in option usage). As you can see (below) nc.traditional can be run as a standalone binary, depending on only libc and linux itself, so if you don\'t have installation permissions, you should be able to just drop the standalone binary somewhere (a filesystem with exec permission of course) and run it like

Can I pipe stdout on one server to stdin on another server?

ssh – How to pipe output from local to remote server

How to redirect output of an already running process

总结

  简单至上!不到万不得已,不造轮子!

完!
2016年11月

版权声明:本文为rongpmcu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/rongpmcu/p/7662807.html