You need to enable JavaScript to run this app. 同一主机下C++应用通过串口实现互相收发消息的方法(Linux环境)
优惠活动
大模型
产品
解决方案
定价
更多

同一主机下C++应用通过串口实现互相收发消息的方法(Linux环境)

Linux同主机C++程序串口通信问题解答

结论

完全可以实现,不需要额外外接物理串口硬件,通过Linux系统自带的伪终端(PTY)能力就能模拟完整的串口通信链路,原有适配物理串口的C++代码几乎不需要修改就能直接复用。

实现原理

Linux的伪终端是成对的内核虚拟设备,分为主端和从端,写入主端的数据会原样透传到从端,写入从端的数据也会原样透传到主端,通信逻辑和物理串口的收发逻辑完全一致,完全可以用来模拟两个程序之间的串口通信链路。

可落地实现方案

方案1:依赖socat快速搭建虚拟串口对(适合快速调试)

  • 首先安装socat工具, Debian/Ubuntu系直接执行apt install socat,RHEL/CentOS系执行yum install socat
  • 执行命令创建虚拟串口对:socat -d -d pty,raw,echo=0 pty,raw,echo=0
  • 命令执行后会输出两个伪终端的路径,例如:

/dev/pts/3
/dev/pts/4

  • 两个C++程序分别打开其中一个路径,按正常Linux串口操作流程配置参数、收发数据即可,两个程序之间就能正常通过串口逻辑互发消息。

方案2:纯C++代码实现(无第三方依赖)

不需要依赖外部工具,直接通过POSIX标准API在程序中创建伪终端对:

  1. 在其中一个C++程序中调用posix_openpt()打开伪终端主端
  2. 依次调用grantpt()、unlockpt()配置主端权限
  3. 调用ptsname()获取伪终端从端的文件路径
  4. 另一个C++程序直接打开上一步得到的从端路径,按串口操作逻辑读写即可

通用串口操作代码片段

// 打开串口/伪终端的通用代码
int fd = open("/dev/pts/3", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0) {
    // 自定义错误处理逻辑
}
struct termios opt;
tcgetattr(fd, &opt);
// 配置波特率,示例为9600
cfsetispeed(&opt, B9600);
cfsetospeed(&opt, B9600);
// 配置数据位、停止位、校验位等参数
opt.c_cflag &= ~CSIZE;
opt.c_cflag |= CS8; // 8位数据位
opt.c_cflag &= ~PARENB; // 无校验
opt.c_cflag &= ~CSTOPB; // 1位停止位
tcsetattr(fd, TCSANOW, &opt);
// 收发数据直接调用read/write系统调用
char buf[1024];
int recv_len = read(fd, buf, sizeof(buf));
int send_len = write(fd, "test msg", 8);

注意事项

  • 用socat创建的伪终端对会随socat进程退出而销毁,需要长期使用可以把socat命令配置为systemd守护进程托管
  • 伪终端的串口参数配置仅需要两边程序保持一致即可,不会有物理串口的电平、丢包等硬件层面的问题,非常适合用来做串口应用的本地调试
  • 普通用户默认拥有自己创建的伪终端的读写权限,不需要额外修改/dev路径下的文件权限

内容的提问来源于stack exchange,提问作者Dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 19:51:02