如何确定哪一对伪tty端口相互连接

时间:2018-04-15 23:06:36

标签: python serial-port pty socat

我有两个python程序,它们通过点到点的串行连接相互通信。为了模拟连接,我使用socat创建一个双向字节流,如下所示:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

控制台返回以下内容,指示现在连接在一起的两个pty端口:

2018/04/15 22:33:03 socat[18197] N PTY is /dev/pts/2
2018/04/15 22:33:03 socat[18197] N PTY is /dev/pts/3
2018/04/15 22:33:03 socat[18197] N starting data transfer loop with FDs [5,5] and [7,7]

然后我必须手动修改两个程序中的每一个以指定每个程序的串行连接,例如:

在程序A.py中:

import serial
...
ser = serial.Serial('/dev/pts/2')

在程序B.py中:

import serial
...
ser = serial.Serial('/dev/pts/3')

我想要的是一个脚本,它将设置socat连接,然后执行A.py,并将一个端口号作为参数传递给它,并执行B.py并将另一个端口号传递给它作为一个论点。

我尝试过一个bash脚本,但是socat命令阻止了我无法捕获其stderr输出以将其放入变量中。如果可以,我可以解析变量,并以我的快乐方式。

有什么想法吗?或者也许是一个更好的方法来做到这一点?

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以使用python中的低级socat类无阻塞地运行Popen。您需要重定向stderr以便可以扫描它以获取pty名称,但是在获得所需信息后,您可以将其移交给后台线程。

import sys
import subprocess as subp
import threading
import shutil
import re

socat_proc = subp.Popen(['socat', '-d', '-d', 'pty,raw,echo=0', 'pty,raw,echo=0'],
    stderr=subp.PIPE)

try:
    # scan output for 2 ptys
    ptylist = []
    for line in socat_proc.stderr:
        line = line.decode().strip()
        print(line)
        pty = re.search(r"N PTY is (.+)", line)
        if pty:
            ptylist.append(pty.group(1))
            if len(ptylist) == 2:
                break

    if socat_proc.poll() is not None:
        print("badness. socat dead.")
        exit(2)

    # background thread consumes proc pipe and sends to stdout
    socat_thread = threading.Thread(target=shutil.copyfileobj, 
        args=(socat_proc.stdout, sys.stdout))
    socat_thread.daemon = True
    socat_thread.start()

    print("pty", ptylist)

    # now you can start your programs...

finally:
    socat_proc.terminate()