【问题标题】:Pseudoterminal master reads what it has just written伪终端主机读取它刚刚写入的内容
【发布时间】:2011-05-19 16:30:35
【问题描述】:

我正在开发一个项目,该项目将使用串行端口连接的“虚拟设备”(python 进程)与也使用串行端口的真实设备连接起来,并且我正在使用伪终端来连接其中的几个(超过 2 个)串行端口通信过程(建模串行设备)在一起,我遇到了一些障碍。

我有一个 python 进程,它生成伪终端,将 pty 的从端符号链接到文件(因此进程可以为文件名创建一个 pyserial 对象),而主端由我的 pty 生成进程保存,并且读;当数据进入一个主控时,数据会被记录下来,然后写入其他主控。如果侦听过程始终存在,则此方法有效。

问题在于虚拟设备何时死机或从未启动(这是该项目的有效用例)。在我的系统上,似乎如果数据被写入 pty 的主端,如果没有任何东西在听从端,则在该主端上调用 read 将返回刚刚写入的数据!这意味着设备会多次接收相同的数据——不好!

例子:

>>master, slave = pty.openpty()
>>os.write(master,"Hello!")
6
>>os.read(master,6)
'Hello!'

我希望对 read() 的调用阻塞,直到从站发送数据。其实这是slave设备的行为——它可以写,然后os.read(slave,1)会阻塞,直到master写数据。

我的“虚拟设备”需要能够传递一个文件名来打开一个串口对象;我试图对主端进行符号链接,但这会导致我的虚拟设备打开 /dev/ptmx,这会创建一个新的伪终端对,而不是链接回已经存在的从端!

有什么办法可以改变主人的行为吗?或者甚至只是获取与从设备相对应的主设备的文件名(不仅仅是 /dev/ptmx)?

提前致谢!

【问题讨论】:

    标签: python pty


    【解决方案1】:

    我很确定这是因为默认情况下回显是打开的。借用Python termios docs,你可以这样做:

    master, slave = os.openpty()    # It's preferred to use os.openpty()
    old_settings = termios.tcgetattr(master)
    new_settings = termios.tcgetattr(master)   # Does this to avoid modifying a reference that also modifies old_settings
    new_settings[3] = new_settings[3] & ~termios.ECHO
    termios.tcsetattr(master, termios.TCSADRAIN, new_settings)
    

    您可以使用以下方法恢复旧设置:

    termios.tcsetattr(master, termios.TCSADRAIN, old_settings)
    

    【讨论】:

    • 我很确定也是这样,但是您想关闭从属端的回声。请记住,pty 是伪终端,主设备就像您的键盘/显示器,而从设备就像它所连接的 /dev/ttyxx 设备。 ptys 模拟终端的所有处理,这在这里可能没有帮助; OP 可能会研究 FIFO 如何作为替代方案工作。
    【解决方案2】:

    如果有人发现这个问题,而 jszakmeister 的回答不起作用,这对我有用。

    openpty 似乎在打开 echo 的情况下以规范模式创建 pty。这不是人们所期望的。您可以使用 tty.setraw 函数更改模式,就像在这个简单的 openpty echo 服务器示例中一样:

    master, slave = os.openpty()
    tty.setraw(master, termios.TCSANOW)
    print("Connect to:", os.ttyname(slave))
    
    while True:
        try:
            data = os.read(master, 10000)
        except OSError:
            break
        if not data:
            break
        os.write(master, data)
    

    【讨论】:

    • 这很奇怪。 openpty 创建一个主/从 pty - 从属是终端,主不是。主端不读canonical,也不关注IGNCR或INLCR等的设置。但是。除非您将其关闭,否则它确实不会与从站相呼应!这不是我所期望的。
    猜你喜欢
    • 2014-06-10
    • 2013-12-16
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 2017-03-10
    • 2012-05-30
    相关资源
    最近更新 更多