当前位置: 首页 > 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.lryc.cn/news/609128.html

相关文章:

  • STM32 串口发送
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘scikit-learn’问题
  • Linux环境下使用Docker搭建多服务环境
  • 学习游戏制作记录(实现克隆攻击的克隆复制和水晶代替克隆)8.3
  • 【gradle】插件那些事
  • 7.28-8.3周报
  • C的数据类型与变量
  • 高质量数据集|从武汉光谷《面向科技情报大模型的高质量数据集建设》招标项目谈起
  • Matlab算法编程示例4:数值解法求解常微分方程的代码实例
  • deep research|从搜索引擎到搜索助手的实践(一)
  • Android 之 MVC架构
  • TVS二极管数据手册解读
  • kraft的设计与实现
  • 【数据结构】队列的顺序存储与链式存储(C语言版)
  • 深度学习中的模型知识蒸馏
  • 【Bluetooth】【Transport层篇】第三章 基础的串口(UART)通信
  • 文本换行问题
  • Jetson Orin NX/NANO+ubuntu22.04+humble+MAVROS2安装教程
  • 【从零开始学习Redis】初识Redis
  • [Oracle] DUAL数据表
  • CAP 理论笔记
  • 推荐系统学习笔记(九)曝光过滤 Bloom Filter
  • 【领域热点】【Vue】Vue 与 WebAssembly:前端性能优化的黄金搭档
  • 自动驾驶中的传感器技术18——Camera(9)
  • Connection refused: no further information: localhost/127.0.0.1:2375
  • docker 可用镜像列表(长期免费)
  • Azure DevOps — Kubernetes 上的自托管代理 — 第 4 部分
  • Docker环境离线安卓安装指南
  • centos9 安装docker engine
  • C++ : 反向迭代器的模拟实现