10

我有一个 PC 软件(操作系统:Win 64 位),它通过物理串行端口 RS232 与机器通信,我想使用 python 为该端口制作一个嗅探器。请注意,我是串口的初学者。

我已经阅读了在线发布的多个文档和问题,但其中大多数要求只使用 3rd-party 软件,但我不能这样做,因为必须将原始字节解码为字符串消息(我有自己的解码/编码方法)。

目前我有这样的设置:

///////////////////       Physical COM1        /////////////
// (PC) Software // <------------------------> // Machine //
///////////////////                            /////////////

我想要一个 python 输出通过 COM1 的任何字节。

期望的行为图(虚拟串口有一个问号,因为我不确定这是否是正确的方法):

///////////////////       Physical COM1        /////////////
// (PC) Software // <------------------------> // Machine //
///////////////////            | Virtual       /////////////
                               | serial port?
                               v
                        //////////////////
                        // (PC) Sniffer // (Python)
                        //////////////////
                               | 
                               v
                         (output bytes)

那些知道 Advanced Serial Port Monitor 的人,它的“spymode”功能正是我试图使用 python 实现的。

我尝试使用 com0com 和 PortMon,但我找不到配置 com0com 以嗅探物理端口的方法(据我观察,com0com 仅生成虚拟端口)并且 PortMon 不支持 Windows 64 位。

我已经被困了好几天了......感谢任何评论/链接/答案。谢谢,

4

3 回答 3

6

你应该通过pySerial

一次只能有一个函数获取串口。

对于单向通信(从机器到PC软件),我能想到的从串口嗅探的唯一方法是从端口1读取并写入端口2,您的机器正在写入端口1并且PC软件已被修改从端口 2 读取。

import serial

baud_rate = 4800 #whatever baudrate you are listening to
com_port1 = '/dev/tty1' #replace with your first com port path
com_port2 = '/dev/tty2' #replace with your second com port path

listener = serial.Serial(com_port1, baudrate)
forwarder = serial.Serial(com_port2, baudrate)

while 1:
    serial_out = listener.read(size=1)
    print serial_out #or write it to a file 
    forwarder.write(serial_out)

要实现全双工(异步双向通信),需要有两个进程,每个方向一个。您将需要以某种方式同步这些过程。一种方法是,一个进程从端口 1 读取,另一个进程写入端口 2,反之亦然。阅读这个问题

于 2013-10-07T18:58:40.177 回答
3

为什么不回显类似的内容:

PC S/W <--> COMn(COM0COM)COMm <--> python monitor & forward <--> COM1 <--> 机器

软件方面,您需要 2 个串行任务,一个打开 COMm,一个打开 COM1,一个中央记录器,COMm 上的任何内容都会被记录,然后转发到 COM1,反之亦然。

于 2013-10-07T18:15:41.730 回答
1

我们可以使用上面的代码不需要经过线程来实现半双工通信。我们将使用一个无限循环和一个变量来指定我们正在读取哪个端口。

import serial
import time

baud_rate = 9600  # whatever baudrate you are listening to
com_port1 = '/dev/ttyUSB0'  # replace with your first com port path
com_port2 = '/dev/ttyUSB1'  # replace with your second com port path

ComRead_timeout = 0.1   # Read timeout to avoid waiting while there is no data on the buffer
ComWr_timeout = 0.1     # Write timeout to avoid waiting in case of write error on the serial port

log = open('log.txt', 'a+')     # Open our log file, to put read data

From_PC_To_Device = True    # this variable is used to specify which port we're gonna read from

listener = serial.Serial(port=com_port1, baudrate=baud_rate, timeout=ComRead_timeout,
                         write_timeout=ComWr_timeout)

forwarder = serial.Serial(port=com_port2, baudrate=baud_rate, timeout=ComRead_timeout,
                          write_timeout=ComWr_timeout)

while 1:
    while (listener.inWaiting()) and From_PC_To_Device:
        serial_out = listener.readline()
        localtime = time.asctime(time.localtime(time.time()))
        Msg = "PC " + localtime + " " + serial_out
        Msg += "\n"
        log.write(Msg)
        print(serial_out)  # or write it to a file
        forwarder.write(serial_out)
    else:
        From_PC_To_Device = False

    while (forwarder.inWaiting()) and not From_PC_To_Device:
        serial_out = forwarder.readline()
        localtime = time.asctime(time.localtime(time.time()))
        Msg = "DEVICE " + localtime + " " + serial_out + "\n"
        log.write(Msg)
        print(serial_out)  # or write it to a file
        listener.write(serial_out)
    else:
        From_PC_To_Device = True
于 2019-01-26T07:18:37.673 回答