如何使用Python制作一个串口嗅探器来嗅探物理串口

13

我有一款运行在Windows 64bit操作系统上的PC软件,通过物理串口RS232与一台机器进行通信,我希望用Python制作一个该串口的嗅探器。请注意,我对串口不是很了解。

我阅读了多篇在线文档和问题,但大部分都建议使用第三方软件,而我不能这样做,因为原始字节必须解码为字符串消息(我有自己的解码/编码方法)。

目前我的设置如下:

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

我希望有一个Python程序可以输出通过COM1传输的所有字节。

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

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

我希望用Python实现Advanced Serial Port Monitor中的"spymode"功能,就像那些熟悉它的人一样。

我尝试过使用com0com和PortMon,但我无法找到配置com0com来嗅探物理端口的方法(据我观察,com0com只能创建虚拟端口),而PortMon不支持Windows 64位。

我已经卡在这里好几天了...如果有任何评论/链接/答案,将不胜感激。 谢谢!

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,反之亦然。 阅读此问题

4
为什么不输出这样的内容:

PC软件 <--> COMn(COM0COM)COMm <--> Python 监视器 & 转发 <--> COM1 <--> 设备

在软件方面,您需要两个串行任务,一个打开COMm,另一个打开COM1,并且还需要一个中央记录器,COMm接收到的任何内容都会被记录然后转发到COM1,反之亦然。

2
我们可以使用上述代码来实现半双工通信,而无需通过线程。我们将使用一个无限循环和一个变量来指定我们正在读取哪个端口。原始答案翻译成"最初的回答"。
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接