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

《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。

相关文章:

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

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

Java集合汇总

Java中的集合框架是Java语言的核心部分&#xff0c;提供了强大的数据结构来存储和操作对象集合。集合框架位于java.util包中&#xff0c;主要可以分为两大类&#xff1a;Collection&#xff08;单列集合&#xff09;和Map&#xff08;双列集合&#xff09;。下面是对它们的总结…...

度小满金融大模型的应用创新

XuanYuan/README.md at main Duxiaoman-DI/XuanYuan GitHub...

Android WebView上传文件/自定义弹窗技术,附件的解决方案

安卓内核开发 其实是Android的webview默认是不支持<input type"file"/>文件上传的。现在的前端页面需要处理的是&#xff1a; 权限 文件路径AndroidManifest.xml <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…...

selenium 输入框、按钮,输入点击,获取元素属性等简单例子

元素操作 nput框 输入send_keys&#xff0c; input框 清除clear()&#xff0c; 按钮 点击click() 按钮 提交submit() 获取元素 tag_name、 class属性值、 坐标尺寸 """ input框 输入1次&#xff0c;再追加输入一次&#xff0c; 清除&#xff0c; 再重新输入&…...

结构体构造函数

【知识点&#xff1a;结构体构造函数】下面两段代码等价。 &#xff08;1&#xff09;结构体构造函数写法 struct LinkNode {int data;LinkNode* next;LinkNode(int x):data(x),next(NULL) {} }; LinkNode* Lnew LinkNode(123); &#xff08;2&#xff09;非结构体构造函数写…...

基于单片机的电子万年历设计

摘要: 本设计以 AT89C51 单片机为主控器,使用 DS1302 时钟芯片、DS18B20 温度芯片、LCD1602 显示模块,利用Proteus 仿真软件和 Keil 编译软件进行了基于单片机的电子万年历仿真,设计的万年历可以在液晶上显示时间,同时还具有时间校准、温度显示等功能。 关键词 :单片机…...

大厂真实面试题(一)

滴滴大数据sql 取出累计值与1000差值最小的记录 1.题目 已知有表t_cost_detail包含id和money两列,id为自增,请累加计算money值,并求出累加值与1000差值最小的记录。 2.分析 本题主要是想找到累加值域1000差距最小的记录,也就是我们要对上述按照id进行排序并且累加,并…...

Docker搭建ELKF日志分析系统

Docker搭建ELKF日志分析系统 文章目录 Docker搭建ELKF日志分析系统资源列表基础环境一、系统环境准备1.1、创建所需的映射目录1.2、修改系统参数1.3、单击创建elk-kgc网络桥接 二、基于Dockerfile构建Elasticsearch镜像2.1、创建Elasticsearch工作目录2.2、上传资源到指定工作路…...

把系统引导做到U盘,实现插上U盘才能开机

前言 有个小伙伴提出了这样一个问题&#xff1a;能不能把U盘制作成电脑开机的钥匙&#xff1f; 小白稍微思考了一下&#xff0c;便做了这样一个回复&#xff1a;可以。 至于为什么要思考一下&#xff0c;这样会显得我有认真思考他提出的问题。 Windows7或以上系统均支持UEF…...

【计算机网络基础知识】

首先举一个生活化的例子&#xff0c;当你和朋友打电话时&#xff0c;你可能会使用三次握手和四次挥手的过程进行类比&#xff1a; 三次握手&#xff08;Three-Way Handshake&#xff09;&#xff1a; 你打电话给朋友&#xff1a;你首先拨打你朋友的电话号码并等待他接听。这就…...

个股场外期权个人如何参与买卖?

个股场外期权作为一种金融衍生品&#xff0c;为个人投资者提供了多样化的投资选择和风险管理工具。想要参与个股场外期权的买卖&#xff0c;以下是一些关键步骤和考虑因素。 文章来源/&#xff1a;财智财经 第一步&#xff1a;选择合适的金融机构 首先&#xff0c;个人投资者需…...

程序猿大战Python——pycharm软件的使用

基础配置 目标&#xff1a;了解PyCharm软件的基础配置处理。 修改背景颜色&#xff1a; Appearance -> Theme 修改字体大小&#xff1a; 搜索font -> Font 例如&#xff0c;一起完成背景、字体大小的修改。 总结&#xff1a; &#xff08;1&#xff09;如果要对PyChar…...

Unity Standard shader 修改(增加本地坐标裁剪)

本想随便找一个裁剪的shader&#xff0c;可无奈的是没找到一个shader符合要求&#xff0c;美术制作的场景都是用的都标准的着色器他们不在乎你的功能逻辑需求&#xff0c;他们只关心场景的表现&#xff0c;那又找不到和unity标准着色器表现一样的shader 1.通过贴图的透明通道做…...

【数据结构】排序——插入排序,选择排序

前言 本篇博客我们正式开启数据结构中的排序&#xff0c;说到排序&#xff0c;我们能联想到我之前在C语言博客中的冒泡排序&#xff0c;它是排序中的一种&#xff0c;但实现效率太慢&#xff0c;这篇博客我们介绍两种新排序&#xff0c;并好好深入理解排序 &#x1f493; 个人主…...

2024.6.9刷题记录

目录 一、1103. 分糖果 II 1.模拟 2.数学 二、312. 戳气球 1.递归-记忆化搜索 2.区间dp 三、2. 两数相加 1.迭代 2.递归-新建节点 3.递归-原节点 四、4. 寻找两个正序数组的中位数 1.堆 2.双指针二分 五、5. 最长回文子串 1.动态规划 2.中心扩展算法 六、6. Z…...

Matlab|遗传粒子群-混沌粒子群-基本粒子群

目录 1 主要内容 2 部分代码 3 效果图 4 下载链接 1 主要内容 很多同学在发文章时候最犯愁的就是创新点创新点创新点&#xff08;重要的事情说三遍&#xff09;&#xff0c;对于采用智能算法的模型&#xff0c;可以采用算法改进的方式来达到提高整个文章创新水平的目的&…...

31|HTTP3:甩掉TCP、TLS 的包袱,构建高效网络

前面两篇文章我们分析了HTTP/1和HTTP/2&#xff0c;在HTTP/2出现之前&#xff0c;开发者需要采取很多变通的方式来解决HTTP/1所存在的问题&#xff0c;不过HTTP/2在2018年就开始得到了大规模的应用&#xff0c;HTTP/1中存在的一大堆缺陷都得到了解决。 HTTP/2的一个核心特性是…...

2 程序的灵魂—算法-2.2 简单算法举例-【例 2.3】

【例 2.3】判定 2000 — 2500 年中的每一年是否闰年&#xff0c;将结果输出。 润年的条件: 1. 能被 4 整除&#xff0c;但不能被 100 整除的年份&#xff1b; 2. 能被 100 整除&#xff0c;又能被 400 整除的年份&#xff1b; 设 y 为被检测的年份&#xff0c;则算法可表示如下…...

Python中的上下文管理器(contextlib)模块

Python中的contextlib模块提供了一些用于创建和管理上下文管理器&#xff08;context managers&#xff09;的工具。上下文管理器是实现了__enter__()和__exit__()方法的对象&#xff0c;它们通常用于确保在代码块执行前后执行某些操作&#xff0c;比如资源获取与释放、设置和重…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...