当前位置: 首页 > news >正文

Linux---终端 I/O 控制接口开发<termios.h>终端输入输出系统

<termios.h>POSIX 标准 中定义的终端 I/O 控制接口,主要用于 Unix/Linux 系统下配置和控制终端设备(TTY)的行为。它是对传统 Unix termio 接口的改进版本,在 BSD 和 System V 系统中都有支持,并被纳入 POSIX.1 标准。

在现代 Linux 系统中,<termios.h> 是控制终端属性的核心头文件,常用于:

  • 串口通信参数配置(波特率、数据位、校验位等)
  • 终端输入模式切换(规范模式 / 非规范模式 / raw 模式)
  • 关闭或开启输入回显(Echo)
  • 自定义特殊控制字符(如 Ctrl+C、Ctrl+Z)
  • 实时输入处理(游戏、实时监控、快捷键响应)

可以说,只要在 Linux/Unix 下精确控制终端或串口,<termios.h> 就是绕不开的工具。


2. 核心数据结构:struct termios

<termios.h> 的所有配置都围绕 struct termios 结构体展开。它保存了终端的全部属性:

struct termios {tcflag_t c_iflag;  // 输入模式标志 (input flags)tcflag_t c_oflag;  // 输出模式标志 (output flags)tcflag_t c_cflag;  // 控制模式标志 (control flags)tcflag_t c_lflag;  // 本地模式标志 (local flags)cc_t     c_cc[NCCS]; // 控制字符数组 (control characters)speed_t  c_ispeed; // 输入波特率 (POSIX.1 不强制要求)speed_t  c_ospeed; // 输出波特率
};

2.1 c_iflag(输入模式标志)

控制终端接收数据时的处理方式,常见标志:

标志作用
IGNBRK忽略输入中的中断条件(break condition)
BRKINT当收到 break 时,产生 SIGINT 信号
ICRNL将输入中的 CR(回车)转换为 NL(换行)
IXON启用输出软件流控制(XON/XOFF 协议)
IXOFF启用输入软件流控制
INPCK启用奇偶校验检测
ISTRIP将 8 位字符的最高位清除(变为 7 位)

2.2 c_oflag(输出模式标志)

控制终端发送数据时的处理方式,常见标志:

标志作用
OPOST启用输出处理(如 NL→CR+NL 转换)
ONLCR将 NL 转换为 CR+NL
OCRNL将 CR 转换为 NL
ONOCR在第 0 列不输出 CR
ONLRETNL 执行 CR 功能

2.3 c_cflag(控制模式标志)

控制终端硬件特性,尤其是串口参数:

标志作用
CLOCAL忽略调制解调器控制线路(本地连接)
CREAD启用接收数据
CSIZE数据位掩码(需配合 CS5/CS6/CS7/CS8 使用)
CS88 位数据位
PARENB启用奇偶校验位
PARODD使用奇校验(默认偶校验)
CSTOPB2 个停止位(默认 1 个)
HUPCL关闭设备时挂断(hang up)调制解调器

2.4 c_lflag(本地模式标志)

控制终端本地行为(不涉及硬件线路):

标志作用
ICANON启用规范模式(行缓冲)
ECHO启用输入字符回显
ECHOE当输入 ERASE 字符时,删除前一个字符并刷新显示
ECHOK当输入 KILL 字符时,清空当前行并刷新显示
ISIG启用信号生成(如 Ctrl+C 产生 SIGINT)
IEXTEN启用扩展功能(如特殊函数键)

2.5 c_cc(控制字符数组)

定义特殊控制字符,通过下标访问,常见下标:

下标含义默认值
VINTR中断字符Ctrl+C
VQUIT退出字符Ctrl+\
VERASE删除字符Backspace
VKILL行删除字符Ctrl+U
VEOF文件结束字符Ctrl+D
VMIN非规范模式下最小读取字符数1
VTIME非规范模式下超时时间(0.1 秒为单位)0

3. 主要 API 函数

3.1 获取和设置终端属性

#include <termios.h>
int tcgetattr(int fd, struct termios *termios_p);
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
  • fd:终端设备文件描述符(通常是 STDIN_FILENO 表示标准输入)
  • optional_actions:生效时机
    • TCSANOW:立即生效
    • TCSADRAIN:等待输出完成后生效
    • TCSAFLUSH:等待输出完成,并丢弃未读输入后生效

3.2 波特率设置

speed_t cfgetispeed(const struct termios *termios_p);
speed_t cfgetospeed(const struct termios *termios_p);
int cfsetispeed(struct termios *termios_p, speed_t speed);
int cfsetospeed(struct termios *termios_p, speed_t speed);

常见 speed 值:B9600, B19200, B38400, B115200 等。

3.3 模式切换函数

void cfmakeraw(struct termios *termios_p);

将终端设置为 raw 模式(非规范、无回显、无信号处理)。

3.4 队列刷新

int tcflush(int fd, int queue_selector);
  • TCIFLUSH:清空输入队列
  • TCOFLUSH:清空输出队列
  • TCIOFLUSH:清空输入和输出队列

3.5 发送 Break 信号

int tcsendbreak(int fd, int duration);
  • 持续发送 0 值比特流(break 信号)

4. 终端工作模式详解

4.1 规范模式(Canonical Mode)

  • 输入以 为单位缓冲,用户按 Enter 后才交给程序
  • 支持行编辑(删除、退格、整行删除)
  • 可以通过特殊字符产生信号(Ctrl+C 中断)
  • 默认模式

4.2 非规范模式(Non-canonical Mode)

  • 输入不经过行缓冲,直接发送给程序
  • 常用于实时响应场景(游戏、串口调试)
  • VMINVTIME 控制读取行为:
    • VMIN = 0, VTIME = 0:非阻塞读取,有数据就读,无数据就返回 0
    • VMIN > 0, VTIME = 0:阻塞直到读取到 VMIN 个字符
    • VMIN = 0, VTIME > 0:等待数据,超时返回 0
    • VMIN > 0, VTIME > 0:读取到第一个字符后开始计时,超时前读到 VMIN 个字符则返回,否则返回已读字符数

4.3 Raw 模式

  • 非规范模式的一种极端形式
  • 关闭所有输入输出处理(不转换 CR/NL,不回显,不产生信号)
  • 常用于需要完全控制输入输出的场景

5. 代码示例

5.1 将终端设为非规范模式(无回显)

#include <termios.h>
#include <unistd.h>
#include <iostream>int main() {struct termios oldt, newt;tcgetattr(STDIN_FILENO, &oldt); // 保存旧设置newt = oldt;// 禁用规范模式和回显newt.c_lflag &= ~(ICANON | ECHO);// 非规范模式读取参数newt.c_cc[VMIN] = 1;  // 至少读取 1 个字符newt.c_cc[VTIME] = 0; // 不超时tcsetattr(STDIN_FILENO, TCSANOW, &newt);std::cout << "请输入字符(按 q 退出):" << std::endl;char c;while (true) {read(STDIN_FILENO, &c, 1);if (c == 'q') break;std::cout << "你输入了: " << c << std::endl;}tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // 恢复原设置return 0;
}

5.2 串口通信配置示例

#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstdio>
#include <cstring>int main() {int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);if (fd < 0) {perror("无法打开串口");return 1;}struct termios tio;memset(&tio, 0, sizeof(tio));// 配置控制模式tio.c_cflag = B115200 | CS8 | CLOCAL | CREAD;// 无奇偶校验tio.c_cflag &= ~PARENB;// 1 个停止位tio.c_cflag &= ~CSTOPB;// 禁用输入处理tio.c_iflag = 0;// 禁用输出处理tio.c_oflag = 0;// 禁用本地模式(非规范、无回显、无信号)tio.c_lflag = 0;// 非规范模式读取参数tio.c_cc[VMIN] = 1;tio.c_cc[VTIME] = 0;// 应用设置tcflush(fd, TCIFLUSH);tcsetattr(fd, TCSANOW, &tio);// 发送数据const char* msg = "Hello Serial\n";write(fd, msg, strlen(msg));// 读取数据char buf[256];ssize_t n = read(fd, buf, sizeof(buf));if (n > 0) {buf[n] = '\0';printf("收到: %s", buf);}close(fd);return 0;
}

6. 高级主题

6.1 信号与终端

在规范模式下,特殊字符(如 Ctrl+C)会产生信号。如果想捕获这些信号,需要:

  • 保留 ISIG 标志
  • 使用 signal()sigaction() 设置信号处理函数

6.2 伪终端(Pseudoterminal)

<termios.h> 不仅用于物理终端,还可用于伪终端(PTY),常用于:

  • 终端模拟器
  • 远程登录服务(SSH)
  • 容器的 TTY 分配

6.3 多平台兼容性

  • <termios.h> 主要在 Linux/Unix 系统可用
  • 在 Windows 下需要使用 WinAPI(如 SetConsoleMode
  • 跨平台项目可使用 ncurses 库或自定义封装层

总结与注意事项

<termios.h> 提供了对终端设备的底层控制能力,涵盖:

  • 终端模式切换(规范 / 非规范 / raw)
  • 输入输出数据处理配置
  • 串口通信参数设置
  • 控制字符自定义
  • 信号与中断处理

使用时的注意事项:

  1. 保存并恢复原设置:程序退出前必须恢复终端原属性,否则可能影响用户后续操作
  2. 位操作修改标志:使用 |= 添加标志,&= ~ 清除标志
  3. 选择正确的生效时机:根据需求选择 TCSANOWTCSADRAINTCSAFLUSH
  4. 错误处理:所有 <termios.h> 函数都有返回值,应检查错误
http://www.dtcms.com/a/503832.html

相关文章:

  • Linux 之 【Linux权限】
  • 网站建设策划书范文案例重庆百度关键词推广
  • 健身器材 网站模版wordpress用户系统
  • 两款实用工具分享:下载与网速测试的轻量级解决方案
  • DVWA靶场实战:Web四大经典漏洞攻防全解析
  • 海外网站测速本地网站建设开发信息大全
  • PowerCat命令操作:PowerShell版的Netcat在渗透测试中的应用
  • 域名注册最好的网站南京设计公司前十名
  • 快速定位源码问题:SourceMap的生成/使用/文件格式与历史
  • 湖南移动官网网站建设wordpress 菜单 分隔
  • 邯郸网站建设服务报价全国住房和城乡建设厅官网
  • leetcode 143 重排链表
  • 元宇宙与职业教育的深度融合:重构技能培养的实践与未来
  • 坪山网站建设哪家便宜帝国cms 网站地图 自定义
  • 双拼输入法:提升打字效率的另一种选择
  • 如何做论坛网站 知乎整套网页模板
  • XSS平台xssplatform搭建
  • SQL入门(structured query language)
  • SAP SD客户主数据查询接口分享
  • RedPlayer 视频播放器在 HarmonyOS 应用中的实践
  • 网站怎么做彩页wordpress 微信打赏
  • Altium Designer创建一个空白工程
  • SciPy 稀疏矩阵
  • 上海网站制作维护南京网站建设索q.479185700
  • 运用API开放接口获取淘宝商品价格信息,对比全网价格
  • 笔记【数据类型,常量,变量】
  • 翠峦网站建设做众筹网站
  • FFmpeg 基本API avformat_find_stream_info函数内部调用流程分析
  • 面试(1)——Java 数据类型和语法基础
  • 网站流量的主要来源有产品设计方案3000字