配置unix telnet以显示和接收十六进制字符的命令

问题描述 投票:0回答:1

我在本地服务器上有一个特殊的应用程序(来自ucsim的8051模拟器),它只在一个端口上传输和期望不可打印的字符。基本上,我正在定义自己的数据格式。

如果我能看到每个字符的十六进制代码返回30列,并且能够键入十六进制字符代码,那么Telnet将是一个完美的程序。问题是,Linux附带的telnet只允许1行十六进制字符,并且可能在接收到某些字符时改变行为。

到目前为止,我最接近的解决方案是在wine中运行realterm程序并选择hex显示,但问题是如果我切换窗口它会锁定。直到我停止服务器发送和接收字符。所以我正在寻找一个原生的Linux解决方案。

至于接收数据,我可以轻松地使用此命令:

nc 127.0.0.1 port | od -tx1 -w30

但是当在数据流出的同一个开放端口上发送数据时,我尝试这个命令:

echo -e -n“\ x11 \ x22 \ x33”| nc 127.0.0.1端口

其中11,22,33是十六进制数字,发送回服务器。问题是当我尝试这个命令时,它只是停止,我必须按CTRL + C退出。

我的逻辑在这里是否正确?

或者是否有更好的命令我可以在unix中使用来查看发送二进制文件的服务器的十六进制字符,还可以传输在本地控制台输入的十六进制字符的二进制代码?

如果realterm程序目前在Linux中运行而不需要葡萄酒,那将是完美的。

附:我很抱歉,如果这个论坛不是这个问题的最佳位置,但就个人而言,我不介意制作一个包含50个命令的unix脚本,如果这就是我所取得的成就,因为我正在寻找的应用程序因为linux尚未存在。

unix terminal binary hex hexdump
1个回答
0
投票

nc将从其标准输入读取并通过网络连接发送该数据。因此,如果您只是希望能够在终端中键入十六进制数字并将相应的二进制数发送到模拟器,则可以使用类似xxd -r -p的数据将数据传输到nc。即将nc 127.0.0.1 ...改为xxd -r -p | nc 127.0.0.1 ...

然后,您可以在return命令中键入“41 42 43 44”(后跟xxd,因为交互式输入是行缓冲的),并且应该将“ABCD”输出到模拟器。 xxd模式中的-r -p将任何非十六进制数字视为分隔符,因此如果需要,可以在十六进制数字对之间放置空格以便于阅读。

如果您希望能够在开发会话期间从各种来源(交互式,从文件中捕获)发送不同类型的数据(十六进制,二进制),那么您可能需要安装第二个持久性nc侦听器一个不同的端口来收集数据并将其提供给现有nc的标准输入。


使用Python程序更新,该程序将从stdin读取十六进制并通过网络连接发送相应的二进制文件,并从连接读取数据并写入十六进制到标准输出。将它保存为类似nethex.py的东西并将其调用为python nethex.py <host> <port>

#!/usr/bin/env python

import binascii
import re
import socket
import sys
import threading


def breakstring(string, maxchars):
    return [ string[pos:(pos + maxchars)]
             for pos in xrange(0, len(string), maxchars) ]

def to_hex(bytes):
    lines = breakstring(binascii.hexlify(bytes), 32)
    return ''.join([ (' '.join(breakstring(line, 2)) + '\n') for line in lines ])


def from_hex(s):
    hexlist = re.sub('[^0-9A-Fa-f]', ' ', s).split()
    pairs = [ '0' + hexstr if len(hexstr)%2 else hexstr for hexstr in hexlist ]
    return binascii.unhexlify(''.join(pairs))


def connect(addr, port):
    conn = None

    infos = socket.getaddrinfo(addr, port, 0, socket.SOCK_STREAM)
    for info in infos:
        fam, typ, proto, fqdn, sa = info
        try:
            conn = socket.socket(fam, typ, proto)
        except socket.error:
            sys.stderr.write('socket: ' + str(se) + '\n')
            continue

        try:
            conn.connect(sa)
        except socket.error as se:
            sys.stderr.write('connect: ' + str(se) + '\n')
            conn.close()
            conn = None
            continue

        break

    return conn


class SockDrainer(threading.Thread):

    def __init__(self, sock, sink):
        super(SockDrainer, self).__init__()
        self.sock = sock
        self.sink = sink

    def run(self):
        drain(self.sock, self.sink)


def drain(sock, dest):
    while True:
        data = sock.recv(2048)
        if not data:
            break
        outdata = to_hex(data)
        dest.write(outdata)
        dest.flush()


def fill(sock, source):
    while True:
        data = source.readline()
        if not data:
            break
        try:
            outdata = from_hex(data)
            sock.send(outdata)
        except socket.error:
            break

    try:
        sock.shutdown(socket.SHUT_WR)
    except socket.error:
        pass


def nethex(addr, port):
    conn = connect(addr, port)

    if conn is not None:
        drainer = SockDrainer(conn, sys.stdout)
        drainer.daemon = True   # thread will not block process termination
        drainer.start()

        fill(conn, sys.stdin)

        drainer.join()          # wait for rx'ed data to be handled

        conn.close()

    return conn is not None


if __name__ == '__main__':
    result = nethex(sys.argv[1], sys.argv[2])
    sys.exit(0 if result else 1)

© www.soinside.com 2019 - 2024. All rights reserved.