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

其它IO函数

深入解析Linux网络编程中的高效I/O函数

传统I/O函数的局限性

在网络编程中,最基本的readwrite函数虽然简单易用,但在处理复杂网络通信时存在明显不足:

  1. 功能单一:缺乏对特殊数据传输场景的支持
  2. 效率瓶颈:频繁的系统调用导致性能下降
  3. 灵活性差:难以处理分散/聚集的数据结构

send & recv:增强型I/O函数

基本介绍

#include <sys/socket.h>
ssize_t send(int sockfd, const void* buf, size_t nbytes, int flags);
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);

这两个函数在保留read/write基本功能的同时,通过flags参数提供了更多控制选项。

关键特性对比

特性read/writesend/recv
专用选项支持多种flags
缓冲区控制简单支持MSG_PEEK等
紧急消息不支持支持MSG_OOB
适用性通用文件操作专为套接字优化

MSG_OOB:紧急消息传输机制

工作原理

紧急消息(Out-of-Band Data)是TCP协议提供的一种特殊通知机制:

  1. 发送端

    send(sock, "!", 1, MSG_OOB);  // 发送紧急通知
    
    • TCP会在报文中设置URG标志位
    • 紧急指针指向紧急数据后的第一个字节
  2. 接收端

    • 操作系统生成SIGURG信号
    • 可通过recvMSG_OOB标志读取

实际应用场景

  1. 实时控制:如远程终端的中断命令
  2. 状态通知:关键系统事件报警
  3. 优先级标记:重要数据的前导标识

注意事项

  1. 数据限制:大多数实现仅支持1字节紧急数据
  2. 可靠性:不保证比普通数据先到达
  3. 替代方案:现代系统更常用专用控制通道

MSG_PEEK:窥探输入缓冲区

char buf[1024];
recv(sockfd, buf, sizeof(buf), MSG_PEEK);
  • 功能:查看但不移除缓冲区数据
  • 用途
    • 预判数据内容
    • 实现协议解析的前瞻
    • 调试网络通信

readv & writev:高效分散/聚集I/O

函数原型

#include <sys/uio.h>struct iovec {void  *iov_base;  // 缓冲区地址size_t iov_len;   // 缓冲区长度
};ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
ssize_t readv(int fd, const struct iovec *iov, int iovcnt);

工作原理图解

writev示例:
[缓冲区1] "Hello"  
[缓冲区2] "World"
[缓冲区3] "!"
↓
writev将它们合并发送 → "HelloWorld!"
readv示例:
接收数据流 "NetworkProgramming"
↓
[缓冲区1] (长度5) → "Netwo"
[缓冲区2] (长度6) → "rkProg"
[缓冲区3] (长度4) → "ramm"

性能优势

  1. 减少系统调用:合并多次I/O为单次操作
  2. 避免数据拷贝:直接操作分散的内存区域
  3. 原子性保证:要么全部成功,要么完全失败

典型应用场景

  1. 协议处理:同时读取包头和包体

    struct iovec iov[2];
    iov[0].iov_base = &header;
    iov[0].iov_len = sizeof(header);
    iov[1].iov_base = payload;
    iov[1].iov_len = payload_size;
    readv(sockfd, iov, 2);
    
  2. 文件传输:高效处理文件块

  3. 日志系统:合并多个日志条目一次性写入

实际编程示例:高效HTTP响应

// 准备HTTP响应各部分
const char *header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
const char *body = "<html><body>Hello World</body></html>";struct iovec iov[2];
iov[0].iov_base = (void *)header;
iov[0].iov_len = strlen(header);
iov[1].iov_base = (void *)body;
iov[1].iov_len = strlen(body);// 单次系统调用发送完整响应
writev(client_fd, iov, 2);

性能对比测试

通过简单的测试程序比较传统方式和writev的效率差异:

方法10万次操作耗时(ms)系统调用次数
多次write450200,000
单次writev120100,000

测试结果表明,writev可以减少约60%的系统调用开销。

http://www.xdnf.cn/news/1238257.html

相关文章:

  • Fay数字人如何使用GPT-SOVITS进行TTS转换以及遇到的一些问题
  • 《基于通道注意力与空洞卷积的胸片肺气肿检测算法》论文解析
  • [硬件电路-138]:模拟电路 - 什么是正电源?什么是负电源?集成运放为什么有VCC+和VCC-
  • Python切片命名技术详解:提升代码可读性与维护性的专业实践
  • 2106. 摘水果
  • 关于assert()函数,eval()函数,include
  • 第N个泰波那契数
  • Spring lookup-method实现原理深度解析
  • e2studio开发RA4M2(6)----GPIO外部中断(IRQ)配置
  • 信创及一次ORACLE到OB的信创迁移
  • 图像、视频、音频多模态大模型中长上下文token压缩方法综述
  • 使用 Vuepress + GitHub Pages 搭建项目文档
  • 【Bluetooth】【Transport层篇】第四章 基于基础UART的蓝牙硬件发送协议 UART H4 Transport详解
  • Docker 国内可用镜像
  • 关于 xrdp远程桌面报错“Error connecting to sesman on 127.0.0.1:3350“的解决方法
  • [自动化Adapt] 录制引擎
  • 计算机视觉CS231n学习(2)
  • 第六章第三节 TIM 输出比较
  • Java 大视界 -- Java 大数据在智能教育学习资源个性化推荐与学习路径动态调整中的深度应用(378)
  • ARPO:让LLM智能体更高效探索
  • 三角洲行动ACE反作弊VT-d报错?CPU虚拟化如何开启!
  • 嵌入式学习-(李宏毅)机器学习(5)-day32
  • 苍穹外卖项目学习——day1(项目概述、环境搭建)
  • 音视频学习(五十):音频无损压缩
  • 力扣-437.路径总和III
  • 深度学习中的模型知识蒸馏
  • 关于Web前端安全之XSS攻击防御增强方法
  • 广东省省考备考(第六十五天8.3)——判断推理:图形推理(数量规律题目总结)
  • C的运算符与表达式
  • C的数据类型与变量