间歇性二进制数据的实时监控

时间:2015-05-04 08:05:12

标签: linux terminal binary buffer monitoring

上下文:监视来自程序的低容量,间歇性流

调试某些程序时,有时需要监视某些输出。当输出为ascii时,没问题,只需在终端(程序本身,或nc,如果它使用TCP或UDP接口,或cat /dev/somedevice,或socat ...,无论如何)运行。

需要:实时监控二进制流...和半解决方案

但有时输出是二进制的。可以将其管道化为odhd的各种咒语,例如od -t d1表示十进制数字,od -t a1表示增强的ascii显示(使用可打印字符的显式不可打印字符)等。

麻烦在于:那些缓冲输入直到它们有一条完整的行来打印(一条线通常适合16个输入字符)。所以基本上直到程序发送16个字符,监控才会显示任何内容。当流量低和/或间歇时,这违背了实时监控的目的。许多协议实际上一次只发送少量字节。

很高兴告诉它"如果你愿意,可以缓冲输入,但是在打印之前不要等待超过延迟x,即使它不会填满一行&#34 ;

man odman hd没有提及任何相关选项。

非溶液

像wireshark这样的重型程序并不是真正的选择:它们只涵盖部分需求而且不可组合。我经常做这样的事情:

{ while read a ; do { echo -n -e 'something' ; } | tee >(od -t d1 >&2) ; done ; } | socat unix-connect:/somesocket stdio | od -t d1

这会监视输出,每次按下终端输入时,都会输入序列""。它运行良好,但终端输出由16字节块缓冲,因此延迟很多。

摘要

如何简单地监视程序的二进制输出而不依赖于字节对齐的延迟?

2 个答案:

答案 0 :(得分:1)

我不知道您正在使用哪个发行版,但请检查您是否拥有most,或者可以安装OPTIONS -b Binary mode. Use this switch when you want to view files containing 8 bit characters. most will display the file 16 bytes per line in hexadecimal notation. A typical line looks like: 01000000 40001575 9C23A020 4000168D ....@..u.#. @... When used with the -v option, the same line looks like: ^A^@^@^@ @^@^U u 9C #A0 @^@^V8D ....@..u.#. @... 。从联机帮助页:

F

不在联机帮助页中,但对您的任务至关重要的是按键most(N.B。大写),它将most置于尾部模式'。在此模式下,只要有新输入,most就会更新。

在缺点方面,stdin无法告知以尾部模式开始,因此您无法管道到其<your_command> >/tmp/output (它会尝试先阅读它显示任何东西)。所以你需要

most -b /tmp/output

在后台,或在其自己的终端中,视情况而定。然后

F

并按 public void importPlug() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { File jar = new File ("/home/karim/Downloads/yarab/VideoPlugin.jar"); JarFile jf = new JarFile(jar); ArrayList <URL> urls = new ArrayList<URL>(); urls.add(jar.toURI().toURL()); java.util.jar.Manifest mf = jf.getManifest(); if (mf != null) { String cp = ((java.util.jar.Manifest) mf).getMainAttributes().getValue("class-path"); if (cp != null) { for (String cpe : cp.split("\\s+")) { File lib = new File(jar.getParentFile(), cpe); urls.add(lib.toURI().toURL()); } } } for (URL u : urls) { System.out.println(u.toString()); } ClassLoader cl = new URLClassLoader(urls.toArray(new URL[urls.size()]), PluginInterface.class.getClassLoader()); //Class c = cl.loadClass("VideoPlugin"); Class c = Class.forName("selenium.VideoPlugin", true, cl); pi = (PluginInterface) c.newInstance(); }

答案 1 :(得分:0)

这是迄今为止我发现的最好的事情,希望有人知道更好的事情。

-w1中使用od选项,或者man hd中的一个示例格式化一次吃掉一个字节的字符串。虽然有一些基于列的显示,但它不能有效地使用终端区域。

{ while read a ; do { echo -n -e 'something' ; } | tee >(od -t d1 >&2) ; done ; } | socat unix-connect:/somesocket stdio | hexdump -v  -e '/1  "%_ad#  "' -e '/1 " _%_u\_\n"'

这显示如下:

0#   _nul_  (plenty of wasted space on the right... )
1#   _1_    (no overview of what's happening...)
2#   _R_
3#   _ _
4#   _+_
5#   _D_
6#   _w_
7#   _d8_
8#   _ht_
9#   _nak_

好处是可以根据自己的背景和品味对其进行配置:

{ while read a ; do { echo -n -e 'something' ; } | tee >(od -t d1 >&2) ; done ; } | socat unix-connect:/somesocket stdio | hexdump -v  -e '/1  "%_ad#    "' -e '/1    "%02X "' -e '/1 " _%_u\_\n"'

这显示如下:

0#    6B  _k_
1#    21  _!_
2#    F6  _f6_
3#    7D  _}_
4#    07  _bel_
5#    07  _bel_
6#    60  _`_
7#    CA  _ca_
8#    CC  _cc_
9#    AB  _ab_

但是,常规hd显示会更有效地使用屏幕区域:

hd

00000000  f2 76 5d 82 db b6 88 1b  43 bf dd ab 53 cb e9 19  |.v].....C...S...|
00000010  3b a8 12 01 3c 3b 7a 18  b1 c0 ef 76 ce 28 01 07  |;...<;z....v.(..|