Команды для настройки unix telnet для отображения и получения шестнадцатеричных символов - PullRequest
0 голосов
/ 09 марта 2019

У меня есть специальное приложение (симулятор 8051 от ucsim) на локальном сервере, которое передает и ожидает непечатные символы только на одном порту. По сути, я определяю свой собственный формат данных.

Telnet была бы идеальной программой, если бы я могла видеть шестнадцатеричные коды каждого возвращаемого символа в 30 столбцах, а также иметь возможность вводить шестнадцатеричные коды символов. Проблема в том, что telnet, поставляемый с Linux, допускает только 1 строку шестнадцатеричных символов и может изменить поведение при получении определенных символов.

Пока что самое близкое решение, которое у меня есть, - это запустить программу realterm в wine и выбрать hex Display, но проблема в том, что она зависает, если я переключаю окна. пока я не остановлю сервер от передачи и получения символов. Поэтому я ищу решение 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 без использования вина.

P.S. Извините, если этот форум не является идеальным местом для этого вопроса, но лично я не возражаю против создания сценария Unix из 50 команд, если это то, что нужно, чтобы получить то, чего я добиваюсь, потому что приложение, которое я ищу для Linux еще не существует.

1 Ответ

0 голосов
/ 10 марта 2019

nc будет считывать данные со своего стандартного входа и отправлять эти данные по сетевому соединению. Поэтому, если вы просто хотите иметь возможность вводить шестнадцатеричные цифры в терминал и отправлять соответствующий двоичный файл в симулятор, вы можете использовать что-то вроде xxd -r -p для передачи данных в nc. То есть изменить nc 127.0.0.1 ... на xxd -r -p | nc 127.0.0.1 ....

Затем вы можете набрать «41 42 43 44» (за которым следует return, потому что интерактивный ввод буферизован строкой) в команду 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)

...