[C++ 网络协议] 多种I/O函数

news2024/12/23 17:17:04

1. Linux的send&recv函数

1.1 send函数和recv函数

#include <sys/socket.h>
ssize_t send(
int sockfd,              //套接字文件描述符
const void* buf,         //保存待传输数据的缓冲地址值
size_t nbytes,           //待传输的字节数
int flags                //传输数据时指定的可选项信息
);
成功返回发送的字节数,失败返回-1
#include <sys/socket.h>
ssize_t recv(
int sockfd,              //套接字文件描述符
const void* buf,         //保存接收数据的缓冲地址值
size_t nbytes,           //接收的字节数
int flags                //接收数据时指定的可选项信息
);
成功返回发送的字节数,失败返回-1

Linux的send和recv函数与windows相比,实际差别不大。

1.2 flags参数(传输时指定的可选项信息)

可选项含义sendrecv
MSG_OOB用于传输带外数据(out-of-band data)
MSG_PEEK验证输入缓冲中是否存在接收的数据
MSG_DONTROUTE数据传输过程中不参照路由表,在本地网络中寻找目的地
MSG_DONTWAIT调用I/O函数时不阻塞,用于非阻塞I/O
MSG_WAITALL防止程序返回,直到接收全部请求的字节数

可以用过"|"运算,同时设置。

1.2.1 MSG_OOB(发送紧急消息)

发送端使用MSG_OOB:

send(sockfd,"123",strlen("123"),MSG_OOB);

紧急消息的发送比较简单,直接指定MSG_OOB可选项即可。

接收端使用MSG_OOB:

void Message_Handle(int signo)
{
    ......
    int recv_len=recv(clientfd,buff,sizeof(buff),MSG_OOB);
    ......
}

int main()
{
    sigaction act;
    act.sa_handler=Message_Handle;
    sigemptyset(&act.sa_mask);
    act.sa_flags=0;
    ......
    fcntl(clientfd,F_SETOWN,getpid());    //(1)
    int state=sigaction(SIGURG,&act,0);   //(2)
    ......
}

fcntl函数的意义:将文件描述符clientfd指向的套接字引发的SIGURG信号处理进程,变为将getpid函数返回值用作ID的进程。

为什么要执行fcntl函数?

因为:如果通过了fork函数创建了子进程,此时文件描述符也会一并复制一份给子进程,这样的话,当SIGURG信号触发时,那应该用哪个进程来处理信号呢?所以这里要使用fcntl函数,来指定处理信号的进程是当前主进程。

综上,接收端使用MSG_OOB必须要有以下步骤:

  1. 执行fcntl函数
  2. 注册SIGURG信号
  3. 在处理函数中接收紧急消息。
发送端顺序:"123","4","567","890";
其中"4"、"890"是紧急消息

接收结果:"123","4","567","0","89";

根据上述结果得知,MSG_OOB的作用,不像我们想象的那样,指定了紧急消息的信息会先到达。并且,我们发送的是一串紧急消息,但最终只读取了一个字节。

实际上,MSG_OOB的作用是:督促数据接收对象尽快处理数据,而不是让信息传输最快。(就像病人送去急诊,MSG_OOB的作用不是让病人尽快到达医院,而是当病人到达医院后,通知医生,让医生来紧急治疗这个病人。这个医生就是程序员)

这是因为,虽然OOB是需要通过单独的通信路径高速传输数据,但是TCP并不另外提供,TCP只是利用其紧急模式来进行传输。

TCP紧急模式工作原理:

当设置了MSG_OOB时,发送端的输出缓冲中的状态为如下形式:

以这个数据缓冲的最左端为偏移量0,基于这个偏移量,这个数据缓冲的尾部之后的一个位置,如上图中的偏移量为3的位置,就存有紧急指针,紧急指针指向紧急消息的下一个位置。当传递时,会告知对方主机,在这个紧急指针的前面的部分都是紧急消息。实际上,只用一个字节来表示紧急消息的信息。即发送端接收到紧急消息只会接收到“0”,而余下的部分,将会由常用输入函数(read)读取。

为什么收到的紧急消息不能直接读取0,90,890?

答:因为这些并不重要,URG_OOB的作用只是督促消息处理,而非紧急传输形式受限的消息。

1.2.2 MSG_PEEK和MSG_DONTWAIT

MSG_PEEK和MSG_DONTWAIT一般是通过"|"同时设置的,用来验证输入缓冲中是否存在接收的数据。但注意,设置了MSG_PEEK选项的recv函数时,读取了输入缓冲里的数据后,并不会删除这个数据。在下一次执行没有设置MSG_PEEK的recv函数时,会再一次读取,并在此次才会删除。所以两者合用,用以调用以非阻塞形式方式验证待读数据存在与否

发送端:
write(sockfd,"123",strlen("123"));

接收端:
int rec_len=recv(sockfd,buff,sizeof(buff),MSG_PEEK|MSG_DONTWAIT);
//这时如果rec_len>0那么就意味着有数据存在。
//此时buff里存有数据123
recv(sockfd,buff,sizeof(buff),0);
//这时读取的buff里仍然是123,因为上一句使用了MSG_PEEK,没有将此数据从输入缓冲中删除。

2. readv&writev函数

#include<sys/uio.h>
ssize_t writev(
int filedes,                //表示数据传输对象的套接字文件描述符,
                            //不仅仅可以是套接字文件描述符,
                            //也可以传递文件或标准输出描述符
const struct iovec* iov,    //iovec结构体数组的地址值,结构体中包含待发送数据的位置和大小
int iovcnt                  //向第二个参数传递的数组长度
);
#include<sys/uio.h>
ssize_t readv(
int filedes,                //表示数据接收对象的套接字文件描述符,
                            //不仅仅可以是套接字文件描述符,
                            //也可以传递文件或标准输出描述符
const struct iovec* iov,    //iovec结构体数组的地址值,结构体中包含数据保存的位置和大小
int iovcnt                  //向第二个参数传递的数组长度
);
struct iovec
{
    void* iov_base;    //缓冲地址
    size_t iov_len;    //缓冲大小
}

readv和writev函数的主要作用是:提高数据通信效率,适当的使用,可以减少I/O函数的调用次数提高性能。

writev(1,ptr,2);

第一个参数1,表示是向控制台输出数据,第二个参数ptr,保存有待发送数据信息的iovec数组指针,第三个参数2,表示从ptr指向的地址开始,读取2个iovec结构体变量,发送这些数据指向的缓冲数据。如图:

如代码:

发送端:
int main()
{
    char buf1[]="ABCDEFG";
    char buf2[]="1234567";
    iovec vec[2];
    vec[0].iov_base=buf1;
    vec[0].iov_len=3;
    vec[1].iov_base=buf2;
    vec[1].iov_len=4;
    writev(1,vec,2);
}
控制台输出为:ABC1234

一次writev即可将两个缓冲buf里的数据分别按字节大小读取出来。

3. Windows的不同

3.1 MSG_OOB的读取与Linux不同

在windows操作系统中,没有如Linux那般的信号处理机制。所以在使用MSG_OOB时,Windows得做特殊处理。即使用select函数在select函数中有个“发送异常的套接字”的参数,这里的异常指的是:不同寻常的程序执行流,所以收到的out-of-band数据也属于异常,所以利用这一特性,可以使用select函数来接收紧急消息。如代码:

发送端:
int main()
{
    ......
    send(hSocket,"4",1,MSG_OOB);
    ......
}
接收端:
int main()
{
    ......
    int result=select(0,&readCopy,0,&exceptCopy,&timeout);
    if(result>0)
    {
        if(FD_ISSET(hRecvSock, &exceptCopy)
        {
            stelen=recv(hRecvSock,buf,sizeof(buf),MSG_OOB);
            ......
        }
        ......
    }
    ......
}

 3.2 重叠I/O(实现Linux的writev和readv函数功能)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1012667.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Layui快速入门之第六节 选项卡

目录 一&#xff1a;基本概念 选项卡依赖element模块 API 元素属性 基本使用&#xff1a; 二&#xff1a;选项卡风格 默认风格 简约风格 ​编辑 卡片风格 三&#xff1a;hash 状态匹配 四&#xff1a;tab相关操作 渲染 tab 添加 tab 删除 tab 切换 tab 自定义…

华为云云耀云服务器L实例评测 | 基于docker部署nacos2.2.3服务

#【有奖征文】华为云云服务器焕新上线&#xff0c;快来亲身感受评测吧&#xff01;# &#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&…

C++之哈希表、哈希桶的实现

哈希表、哈希桶的实现 哈希概念哈希冲突哈希函数哈希冲突解决闭散列哈希表闭散列实现哈希表的结构哈希表的插入哈希表的查找哈希表的删除 开散列开散列概念哈希表的结构哈希表的插入哈希表的查找哈希表的删除 哈希概念 顺序结构以及平衡树中&#xff0c;元素关键码与其存储位置…

Postman使用_Tests Script(断言测试)

断言测试可以在Collection、Folder和Request的 pre-request script 和 test script中编写&#xff0c;测试脚本可以检测请求响应的各个方面&#xff0c;包括正文、状态代码、头、cookie、响应时间等&#xff0c;只有测试符合自定义的要求后才能通过。 pm对象提供了测试相关功能…

LiveNVR监控流媒体Onvif/RTSP功能-支持海康摄像头海康NVR通过EHOME协议ISUP协议接入分发视频流或是转GB28181

LiveNVR支持海康NVR摄像头通EHOME接入ISUP接入LiveNVR分发视频流或是转GB28181 1、海康 ISUP 接入配置2、海康设备接入2.1、海康EHOME接入配置示例2.2、海康ISUP接入配置示例 3、通道配置3.1、直播流接入类型 海康ISUP3.2、海康 ISUP 设备ID3.3、启用保存3.4、接入成功 4、相关…

SadTalker 让图片说话

参考&#xff1a;https://github.com/OpenTalker/SadTalker 其他类似参考&#xff1a;https://www.d-id.com/ 输入图片加音频产生2d视频 安装使用 1、拉取github&#xff0c;下载对应安装库 2、下载对应模型baidu网盘 新建checkpoints&#xff0c;把下载sadtalker里模型拷贝进…

Docker 的使用

一、Docker 的作用和优势 软件集装箱化平台&#xff0c;可让开发者构建应用程序时&#xff0c;将它与环境一起打包到一个容器中&#xff0c;发布应用到任意平台中。 能在单台机器上运行多个Docker微容器&#xff0c;而每个微容器里都有一个微服务或独立应用&#xff0c; 如&am…

汽车行业新闻稿怎么写?怎么写关于汽车的新闻稿?

撰写汽车行业新闻稿需要遵循一定的结构和要点&#xff0c;以确保内容准确、清晰&#xff0c;并能吸引读者的兴趣。以下是关于汽车的新闻稿的一些写作要点和建议&#xff0c;接下来伯乐网络传媒就来给大家分享一下&#xff1a; 标题醒目&#xff1a;新闻稿的标题应该简洁明了&am…

多视角姿势估计:TEMPO: Efficient Multi-View Pose Estimation, Tracking, and Forecasting

论文作者&#xff1a;Rohan Choudhury,Kris Kitani,Laszlo A. Jeni 作者单位&#xff1a;Carnegie Mellon University 论文链接&#xff1a;http://arxiv.org/abs/2309.07910v1 内容简介&#xff1a; 1&#xff09;方向&#xff1a;多视角姿势估计模型 2&#xff09;应用&…

$value$plusargs字符串参数传递后如何随机

文章目录 前言一、背景二、解决办法总结 前言 在仿真过程中&#xff0c;经常在命令行通过$value$plusargs传递一个字符串到环境中&#xff0c;去选择不同的sequence&#xff0c;但是&#xff0c;有些时候需要随机选择其中某几个seq&#xff0c;而只有整数和枚举类型可以随机&a…

Ubuntu20.04安装Nvidia显卡驱动、CUDA11.3、CUDNN、TensorRT、Anaconda、ROS/ROS2

1.更换国内源 打开终端&#xff0c;输入指令&#xff1a; wget http://fishros.com/install -O fishros && . fishros 选择【5】更换系统源&#xff0c;后面还有一个要输入的选项&#xff0c;选择【0】退出&#xff0c;就会自动换源。 2.安装NVIDIA驱动 这一步最痛心…

腾讯mini项目-【指标监控服务重构】2023-08-03

今日已办 a&#xff0c;b两组的trace放到一个分支里 可以看到先前的没看到的 profile trace 的耗时&#xff0c;是由于时间跨度较长&#xff0c;没有滑动到 trace 末尾 明日待办 组长会议汇报项目进度和问题

我跟面试官说MySQL单表数据量不要超过两千万,面试官不信

&#x1f449;导读 作为一个合格的 DBA&#xff0c;在遇到线上单表数据量超过千万级别的时候&#xff0c;往往会建议用户通过分表来缩减单表数据量&#xff0c;当用户问为什么单表数据量不能超过千万时&#xff0c;DBA 往往会说&#xff1a;单表数据量超过千万&#xff0c;会影…

搜好货API接口解析,实现获得搜好货商品详情

要解析搜好货API接口并实现获取搜好货商品详情&#xff0c;你需要按照以下步骤进行操作&#xff1a; 了解搜好货开放平台&#xff1a;访问搜好货开放平台官网&#xff0c;找到API接口相关的开发者文档、指南等信息。注册开发者账号&#xff1a;在搜好货开放平台上注册一个开发…

C#开发的OpenRA游戏之调试菜单2

C#开发的OpenRA游戏之调试菜单2 前面已经分析了怎么样通过选项参数来打开这个调试界面,当创建游戏之后,从游戏里选择参数按钮,就会弹出下面的界面,如果没有选择调试参数是没有Debug这一页选项卡: 上面调试的选项是非常有用的,否则不能快速地测试游戏,不能快速地开发新的…

列表页面新增 字段查询 ,点击查询后,前端页面和后端控制台 出现红色报错信息,查询数据失败。

项目场景&#xff1a; 项目场景简述&#xff1a; 列表页面新增 字段查询 &#xff0c;点击查询后&#xff0c;前端页面和后端控制台 出现红色报错信息&#xff0c;查询数据失败。 问题描述 问题描述&#xff1a; <el-select v-model"dataForm.engineerId" clea…

类和对象(4)

文章目录 1. C/C内存分布2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3.C内存管理方式new/delete3.1 new/delete操作内置类型3.2 new/delete操作自定义类型 4. operator new和operator delete函数&#xff08;重点&#xff09;4.1底层原理 5.malloc/free…

24届双非本科找工作到底有多难

记录一下自己的找工作过程&#xff0c;今天笔试失败感觉整个人都颓废了(那家公司真的是我的目标情司&#xff0c;呜呜呜&#xff0c;感觉我是废物)。 再加上不考虑出省&#xff0c;感觉找工作太难了 介绍一下自己情况&#xff1a;三个省奖&#xff08;开发类的&#xff0c;负责…

性能测试模型-业务模型、策略模型、数据模型

针对性能测试具体方案的设计进行抽象和总结,将其归纳为6个性能测试模型。 业务模型 业务模型是一组功能点或接口的集合及其占比情况,用于合理地模拟生产上真实的业务发生场景 在实施范围上,业务模型为本项目明确实施范围,梳理涉及的业务系统及其完整链路等 在实施结果价值…

提示词加神秘咒语让大模型更加聪明

谷歌团队研究发现&#xff0c;提示词加上神秘咒语深呼吸(take a deep breath&#xff09;结合大家已经熟悉的“一步一步地想”&#xff08;Let’s think step by step&#xff09;&#xff0c;大模型在数据集上的成绩就提升了12%。而且这个最有效的提示词&#xff0c;是AI自己找…