python 如何使用 /dev/ptmx 创建虚拟串口?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2174071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:58:57  来源:igfitidea点击:

how to use /dev/ptmx for create a virtual serial port?

pythonlinuxserial-port

提问by linjunhalida

I have a program, using pyserial, and I want to test it without using a real serial port device.

我有一个程序,使用 pyserial,我想在不使用真正的串行端口设备的情况下对其进行测试。

In windows, I use com0com, and in linux, I know there is a method to create virtual serial port pair without using additional program.

在windows中,我使用com0com,在linux中,我知道有一种方法可以在不使用额外程序的情况下创建虚拟串口对。

so I look up the manual, and found pts, /dev/ptmx, but I don't know how to create a pair by following the manual, can anyone give me a example?

所以我查了手册,找到了pts,/dev/ptmx,但我不知道如何按照手册创建一对,谁能给我举个例子?

I tried(in python):

我试过(在python中):

f = open("/dev/ptmx", "r")

and it works, /dev/pts/4 is created.

它有效,/dev/pts/4 被创建。

and I tried:

我试过:

f = open("/dev/4", "w")

and the result is:

结果是:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 5] Input/output error: '/dev/pts/4'

edit: I found a solution(workround), using socat.

编辑:我找到了一个解决方案(解决方法),使用 socat。

socat PTY,link=COM8 PTY,link=COM9

then COM8 COM9 are created as virtual serial port pair.

然后将 COM8 COM9 创建为虚拟串行端口对。

采纳答案by Alex Martelli

Per the docs, you need ptsnameto get the name of the slave-side of the pseudo-terminal, and also, quoting the docs,

根据docs,您需要ptsname来获取伪终端从属端的名称,并且还需要引用文档,

Before opening the pseudo-terminal slave, you must pass the master's file descriptor to grantpt(3) and unlockpt(3).

在打开伪终端slave之前,必须将master的文件描述符传递给grantpt(3)和unlockpt(3)。

You should be able to use ctypesto call all of the needed functions.

您应该能够使用ctypes来调用所有需要的函数。

回答by Aquiles

I was trying to make an application that made use of virtual serial ports in order to communicate with some remote devices using TCP/Serial conversion... and I came across to a problem similar to yours. My solution worked out as follows:

我试图制作一个使用虚拟串行端口的应用程序,以便使用 TCP/串行转换与某些远程设备进行通信……但我遇到了与您类似的问题。我的解决方案如下:

import os, pty, serial

master, slave = pty.openpty()
s_name = os.ttyname(slave)

ser = serial.Serial(s_name)

# To Write to the device
ser.write('Your text')

# To read from the device
os.read(master,1000)

Although the name of the port of the master is the same if you check (/dev/ptmx) the fd is different if you create another master, slave pair, so reading from the master gets you the message issued to his assigned slave. I hope this helps you or anyone else that comes across a problem similar to this one.

尽管如果您检查 (/dev/ptmx) 时主端口的名称是相同的,但如果您创建另一个主从对,则 fd 是不同的,因此从主读取可以将消息发送给他指定的从。我希望这可以帮助您或遇到与此问题类似的问题的任何其他人。

回答by t0mm13b

I don't know python but I can point you in the right direction: look hereat a C code sample. Here's the manpage for the /dev/ptmx. Make sure the permissions and owner is correct!. Here is the poster on the linuxquestions forumon how to use it from C.

我不知道 python,但我可以为你指出正确的方向:看看这里的 C 代码示例。这是/dev/ptmx的手册页。确保权限和所有者正确!。这是 linuxquestions论坛上关于如何从 C 使用它的海报。

回答by Thomas Wouters

You should consider using the ptymodule instead, which should take care of this for you. (it opens /dev/ptmx or calls openptyor opens another appropriate device, depending on the platform.)

您应该考虑改用该pty模块,它应该会为您解决这个问题。(它打开 /dev/ptmx 或调用openpty或打开另一个适当的设备,具体取决于平台。)

回答by badp

You could build a dummy object that implements the same interface as the pySerialclasses you use, but do something completely different and easily replicable like reading from and writing to files/terminal/etc.

您可以构建一个虚拟对象,该对象实现与pySerial您使用的类相同的接口,但做一些完全不同且易于复制的事情,例如读取和写入文件/终端等。

For example:

例如:

class DummySerial():
  #you should consider subclassing this
  def __init__(self, *args, **kwargs):
    self.fIn = open("input.raw", 'r')
    self.fOut = open("output.raw", 'w')
    pass
  def read(self, bytes = 1):
    return self.fIn.read(bytes)
  def write(self, data):
    self.fOut.write(data)
  def close(self):
    self.fIn.close()
    self.fOut.close()
  #implement more methods here

If it quacks like a duck and it ducks like a duck...

如果它像鸭子一样嘎嘎叫,它像鸭子一样鸭叫......