《TCP/IP网络编程》(第十三章)多种I/O函数(2)

使用readvwritev函数可以提高数据通信的效率,它们的功能可以概括为**“对数据进行整合传输及发送”**。
即使用writev函数可以将分散在多个缓冲中的数据一并发送,使用readv函数可以由多个缓冲分别接受,所以适当使用他们可以减少I/O函数的调用次数。

1.readvwritev函数

readv()函数
用于从文件描述符中读取数据,并存储在多个缓冲区中

ssize_t readv(
int fd, //文件描述符。
const struct iovec *iov, //指向 iovec 结构体数组的指针,iovec 结构体定义了一个缓冲区。
int iovcnt//iovec 结构体数组的元素个数。
);//iovec 结构体
struct iovec {void *iov_base; //指向缓冲区的起始地址(基地址)size_t iov_len; //缓冲区的长度,即需要传输的字节数
};

示例代码

#include<stdio.h>
#include<sys/uio.h>
#define BUF_SIZE 100
int main(int argc, char *argv[])
{struct iovec vec[2];char buf1[BUF_SIZE] = {0, };char buf2[BUF_SIZE] = {0, };int str_len;//设置两个缓存区,第一个存储5个字节,剩下的给第二个缓冲区vec[0].iov_base = buf1;vec[0].iov_len = 5;vec[1].iov_base = buf2;vec[1].iov_len = BUF_SIZE;str_len = readv(0, vec, 2);//第一个参数是0,即接受键盘输入printf("Read total bytes: %d \n", str_len);printf("First message: %s \n", buf1);printf("Second message: %s \n", buf2);return 0;
}

在这里插入图片描述

writev()函数
用于将多个缓冲区中的数据写入文件描述符,这种方法称为“聚集写”或“向量写”。

ssize_t writev(
int fd, //文件描述符
const struct iovec *iov, //指向 iovec 结构体数组的指针,iovec 结构体定义了一个缓冲区。
int iovcnt//iovec 结构体数组的元素个数。
);//iovec 结构体
struct iovec {void *iov_base; //指向缓冲区的起始地址(基地址)size_t iov_len; //缓冲区的长度,即需要传输的字节数
};

示例代码

#include<stdio.h>
#include<sys/uio.h>int main(int argc, char *argv[]){struct iovec vec[2];//有两个缓冲char buf1[] = "1234567890";char buf2[] = "ABCDEFGHIJ";int str_len;vec[0].iov_base = buf1;vec[0].iov_len = 10;vec[1].iov_base = buf2;vec[1].iov_len = 10;str_len = writev(1, vec, 2);//第一个参数是1,所以是向控制台输出puts("");printf("writev bytes: %d \n", str_len);
}

在这里插入图片描述

2.在Windows中实现紧急消息机制

在《TCP/IP网络编程》(第十三章)多种I/O函数(1)中已经基于Linux平台实现了MSG_OOB机制,但是是基于Linux的信号处理机制,所以无法直接移植到Windows平台。

若要在Windows平台上实现该机制,则需要通过select()函数,该函数简介参考《TCP/IP网络编程》(第十二章)I/O复用(1)

PS:MSG_OOB在select()监视下会被视为异常数据
发送端代码

#include<stdio.h>
#include<stdlib.h>
#include<winsock2.h>#define BUFSIZE 30
void ErrorHandling(char* message);int main(int argc, char* argv[]){WSADATA wsa;SOCKET hSocket;SOCKADDR_IN sendAddr;if(argc!=3){printf("Usage : %s <IP> <port>\n", argv[0]);exit(1);}if(WSAStartup(MAKEWORD(2,2), &wsa) != 0){ErrorHandling("WSAStartup() error!");}hSocket = socket(PF_INET, SOCK_STREAM, 0);memset(&sendAddr, 0, sizeof(sendAddr));sendAddr.sin_family = AF_INET;sendAddr.sin_addr.s_addr = inet_addr(argv[1]);sendAddr.sin_port = htons(atoi(argv[2]));if(connect(hSocket, (SOCKADDR*)&sendAddr, sizeof(sendAddr)) == SOCKET_ERROR)ErrorHandling("connect() error!");send(hSocket, "123", 3, 0);send(hSocket, "4", 1, MSG_OOB);//带外数据在select的监视中,会被视为异常数据send(hSocket, "567", 3, 0);send(hSocket, "890", 3, MSG_OOB);//只把最后一个字节0作为紧急信息发送closesocket(hSocket);WSACleanup();return 0;
}void ErrorHandling(char* message){fputs(message, stderr);fputc('\n', stderr);exit(1);
}

接受端代码

#include<stdio.h>
#include<stdlib.h>
#include<winsock2.h>#define BUFSIZE 30
void ErrorHandling(char *);int main(int argc, char *argv[]){WSADATA wsa;SOCKET hAcptSock, hRecvSock;SOCKADDR_IN sendAdr, recvAdr;int sendAdrSz,strLen;char buf[BUFSIZE];int result;fd_set read,except,read_copy,except_copy;struct timeval timeout;if(argc != 2){printf("Usage : %s <port>\n", argv[0]);exit(1);}if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)ErrorHandling("WSAStartup() error!");hAcptSock = socket(PF_INET, SOCK_STREAM, 0);if(hAcptSock == INVALID_SOCKET)ErrorHandling("socket() error");memset(&recvAdr, 0, sizeof(recvAdr));recvAdr.sin_family = AF_INET;recvAdr.sin_addr.s_addr = htonl(INADDR_ANY);recvAdr.sin_port = htons(atoi(argv[1]));if(bind(hAcptSock, (SOCKADDR*)&recvAdr, sizeof(recvAdr)) == SOCKET_ERROR)ErrorHandling("bind() error");if(listen(hAcptSock, 5) == SOCKET_ERROR)ErrorHandling("listen() error");sendAdrSz = sizeof(sendAdr);hRecvSock = accept(hAcptSock, (SOCKADDR*)&sendAdr, &sendAdrSz);FD_ZERO(&read);    // 清空reads集合FD_ZERO(&except);  // 清空except集合FD_SET(hRecvSock, &read);		// 将套接字添加到reads集合FD_SET(hRecvSock, &except);		// 将套接字添加到except集合while(1){read_copy = read;except_copy = except;timeout.tv_sec = 5;timeout.tv_usec = 0;result = select(0, &read_copy, 0, &except_copy, &timeout);//开始监视文件描可读数集和与异常集合if(result>0){if(FD_ISSET(hRecvSock, &except_copy)){//使用FD_ISSET宏检查套接字是否在异常集合中。//如果是,表示发生了异常事件,此时会调用recv函数并指定MSG_OOB标志来接收带外数据strLen = recv(hRecvSock, buf, BUFSIZE-1, MSG_OOB);buf[strLen] = 0;printf("urgent message: %s \n", buf);}if(FD_ISSET(hRecvSock, &read_copy)){// 如果检测到读事件strLen = recv(hRecvSock, buf, BUFSIZE-1, 0);if(strLen == 0){break;closesocket(hRecvSock);}else{buf[strLen] = 0;printf("normal message: %s", buf);}}}}closesocket(hAcptSock);closesocket(hRecvSock);WSACleanup();return 0;
}void ErrorHandling(char *message){fputs(message, stderr);fputc('\n', stderr);exit(1);
}

在这里插入图片描述
优先接受MSG_OOB信息4和0。

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

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

相关文章

压力测试-性能指标-Jmeter使用-压力测试报告

文章目录 1.压测目的2.性能指标3.Jmeter3.1Jmeter使用3.1.1 运行Jmeter3.1.2 添加线程组3.1.3设置HTTP请求3.1.4 设置监视器 3.2 查看Jmeter压测结果3.2.1 查看结果树3.2.2 查看汇总报告3.2.3 查看聚合报告3.2.4 查看汇总图 1.压测目的 内存泄漏&#xff1a;OOM&#xff0c;重…

Hadoop3:MapReduce源码解读之Map阶段的CombineFileInputFormat切片机制(4)

Job那块的断点代码截图省略&#xff0c;直接进入切片逻辑 参考&#xff1a;Hadoop3&#xff1a;MapReduce源码解读之Map阶段的Job任务提交流程&#xff08;1&#xff09; 6、CombineFileInputFormat原理解析 类的继承关系 与TextInputFormat切片机制的区别 框架默认的TextI…

TPC-H建表语句(MySQL语法)

TPC-H测试集介绍 TPC-H&#xff08;Transaction Processing Performance Council, Standard Specification, Decision Support Benchmark, 简称TPC-H&#xff09;是一个非常权威数据库基准测试程序&#xff0c;由TPC组织制定。 TPC-H定义了一个包含8个表的模式&#xff08;Sc…

敏捷开发:拥抱变化,持续交付价值的艺术

目录 敏捷开发&#xff1a;拥抱变化&#xff0c;持续交付价值的艺术 引言 第一部分&#xff1a;敏捷开发是什么&#xff1f; a.定义&#xff1a;敏捷开发的基本概念和核心原则 b.历史&#xff1a;敏捷宣言的诞生和敏捷开发的历史背景 c.价值观&#xff1a;敏捷宣言的12条…

戴尔R720服务器(4)虚拟机性能测试

物理机环境 机型戴尔R720系统环境PVECPUE5-2660V2 2.2GHz 双路内存1333MHz 单通道内存1333MHz 双通道硬盘用6块转速1万的2.5寸盘组的RAID5&#xff0c;使用了H310mini阵列卡 ‍ 测试工具&#xff1a;Sysbench。一个跨平台的基准测试工具&#xff0c;用于评估系统性能&#xff…

[消息队列 Kafka] Kafka 架构组件及其特性(一)

工作中的消息队列用的是Kafka&#xff0c;一直没有系统的了解&#xff0c;这边集中整理一下。 目录 Kafka主要组件有十个部分。 1.Broker&#xff08;服务器&#xff09; 2.Record&#xff08;消息&#xff09; 3.Producer&#xff08;生产者&#xff09; 4.Consumer&…

Coolmuster Android助手评测:简化Android到电脑的联系人传输

产品概述 Coolmuster Android助手是一款旨在简化Android设备与计算机之间数据管理和传输过程的全面工具。它以用户友好的界面和全面的功能&#xff0c;成为寻求高效数据管理解决方案的Android用户的热门选择。 主要特点和功能Coolmuster Android助手拥有一系列使其成为管理Andr…

XR模拟的巨大飞跃,Varjo如何塑造战斗机飞行员培训的未来

随着虚拟现实技术的不断发展&#xff0c;拥有直通功能的XR技术被广泛应用于各种虚拟培训项目之中&#xff0c;能够完美混合虚拟与现实环境的XR技术能够最大限度的优化培训效果并有效减少仿真培训中的成本消耗。 技术总部位于加利福尼亚州南旧金山的Aechelon是集培训、模拟和娱乐…

盛夏之约,即将启程,2024中国北京消防展将于6月26举行

盛夏之约&#xff0c;即将启程&#xff0c;2024中国北京消防展将于6月26举行 盛夏之约&#xff0c;即将启程&#xff01;备受瞩目的2024中国&#xff08;北京&#xff09;消防技术与设备展览会将于6月26-28 日在北京.首钢会展中心盛大召开。作为消防安全和应急救援的年度盛会&…

ssh远程管理和nfs共享存储服务

ssh远程管理和nfs共享存储服务 一、Openssh概念 1、定义 ssh是一种安全通道协议&#xff0c;用来实现字符界面的远程登录。还可以进行远程复制&#xff0c;远程文本传输。 ssh对通信双方的数据进行加密。 2、登录方式 用户名和密码登录 密钥对认证方式&#xff08;可以实…

转让北京海淀成立满1年拍卖公司许可证条件和流程

拍卖经营批准证书是拍卖企业经营所需的许可&#xff0c;是为了维护拍卖秩序&#xff0c;保护拍卖活动各方合法权益而颁发的合法凭证。其中个人物品&#xff0c;公司物品&#xff0c;或者国有资源的拍卖可通过普通拍卖资质进行拍卖。而文物古董拍卖类的需取得文物拍卖经营许可证…

力扣算法题:将数字变为0的操作次数--多语言实现

无意间看到&#xff0c;力扣存算法代码居然还得升级vip。。。好吧&#xff0c;我自己存吧 golang&#xff1a; func numberOfSteps(num int) int {steps : 0for num > 0 {if num%2 0 {num / 2} else {num - 1}steps}return steps } javascript: /*** param {number} num…

Cortex系列详解

Cortex系列属于ARMv7架构(ARM公司在经典处理器ARM11以后的产品改用Cortex命名) 一、Cortex-A系列 “A”系列面向尖端的基于虚拟内存的操作系统和用户应用。 A 系列处理器适用于具有高计算要求、运行丰富操作系统以及提供交互媒体和图形体验的应用领域。 具体案例如:智能手…

【java结构】巧计各种层(dao、service等)的意思

记记记&#xff01;&#xff01; 1. **DAO 和 Service 巧记方法**方法一&#xff1a;比喻法方法二&#xff1a;口诀法 2. **如何记住Spring项目的目录结构**缩略词法联想法 3. **一个完整的记忆技巧&#xff1a;角色扮演法**故事示例&#xff1a; 4. **用日常用语概括**总结 sr…

期货短线交易的核心技术是什么

一、市场分析是短线交易的基础&#xff1a; 技术分析在短线交易中尤为重要&#xff0c;包括K线图、均线系统、成交量与持仓量等指标。K线图可以帮助交易者识别关键价格形态和趋势线&#xff0c;从而判断市场走势。均线系统则可以利用短期均线交叉作为买卖信号&#xff0c;如金…

多页面项目的按需打包

为什么需要按需打包&#xff1f; 现代框架像vue、react、svelte框架等是单页面框架&#xff0c;如果想实现多页面&#xff0c;需要借助webpack和vite等打包工具进行配置&#xff0c;但是多页面就会有一个问题&#xff0c;如果本次只改动了一个页面的逻辑难道要全部打包吗&…

electron-vite如何解决跨域问题

electron.vite.config.mjs代码如下 server: {port: 1024,hmr: true,proxy: {"/api": {//这里如实添加自己的后端接口前缀target: "http://localhost:7090",changeOrigin: true,pathRewrite: {"^api": "/api"}}}}, 接下来就是最重要的一…

course-nlp——6-rnn-english-numbers

本文参考自https://github.com/fastai/course-nlp。 使用 RNN 预测数字的英文单词版本 在上一课中&#xff0c;我们将 RNN 用作语言模型的一部分。今天&#xff0c;我们将深入了解 RNN 是什么以及它们如何工作。我们将使用尝试预测数字的英文单词版本的问题来实现这一点。 让…

K210视觉识别模块学习笔记4: (MaixHub)训练与使用自己的模型_识别字母

今日开始学习K210视觉识别模块: 模型训练与使用_识别字母 亚博智能的K210视觉识别模块...... 固件库: maixpy_v0.6.2_52_gb1a1c5c5d_minimum_with_ide_support.bin 文章提供测试代码讲解、完整代码贴出、测试效果图、测试工程下载 这里也算是正式开始进入到视觉识别的领域了…

【Python】教你彻底了解Python中的正则表达式

​​​​ 文章目录 一、正则表达式的基本概念1. 元字符2. 特殊序列 二、Python中正则表达式的使用方法1. 导入re模块2. 匹配&#xff08;match&#xff09;3. 搜索&#xff08;search&#xff09;4. 查找所有匹配&#xff08;findall&#xff09;5. 替换&#xff08;sub&#…