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

<winsock>重叠IO模型

 基于事件判断io完成


send程序

#include <stdio.h>
#include <winsock2.h>#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable : 4996)int main()
{WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){printf("WSAStartup 失败\n");system("pause");return 1;}// 创建 重叠模型的套接字SOCKET HSocket = WSASocket(PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);if (HSocket == INVALID_SOCKET){printf("WSASocket 失败\n");WSACleanup();system("pause");return -1;}//和往常一样创建客户端连接sockaddr_in SendAddr;memset(&SendAddr, 0, sizeof(SendAddr));SendAddr.sin_family = AF_INET;SendAddr.sin_port = htons(4567); // 服务器端口SendAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 服务器 IP本地还回地址if (connect(HSocket, (LPSOCKADDR)&SendAddr, sizeof(SendAddr)) == SOCKET_ERROR){printf("WSASocket 失败\n");WSACleanup();system("pause");return -1;}//创建一个初始无信号手动重置的事件对象WSAEVENT evobj = WSACreateEvent();//创建一个WSAOVERLAPPED 结构体变量WSAOVERLAPPED overlapped;memset(&overlapped, 0, sizeof(overlapped));overlapped.hEvent = evobj;//保存待传输的数据大小 和数据存储的地址WSABUF dataBuf;char msg[] = "网络编程";dataBuf.buf = msg;dataBuf.len = strlen(msg) + 1;//保存实际发送字节数DWORD sendedBytes = 0;//开始传输数据//如果不返回SOCKET_ERROR,说明数据已经传输完成了if (WSASend(HSocket, &dataBuf, 1, &sendedBytes, 0, &overlapped, NULL) == SOCKET_ERROR){   //判断错误码是不是WSA_IO_PENDING,说明数据没有传输完成if (WSAGetLastError() == WSA_IO_PENDING){puts("正在后台传输数据中");//永久等待 一个事件WSAWaitForMultipleEvents(1, &evobj, TRUE, WSA_INFINITE, FALSE);//事件有信号了,用这个函数获得io处理的结果.如果fwait设置为true,将等待io的完成,函数阻塞;如果设置为false并且调用时io的未完成 ,函数立即返回falseBOOL isok= WSAGetOverlappedResult(HSocket, &overlapped, &sendedBytes, FALSE, NULL);if(!isok){printf("WSAGetOverlappedResult 失败 %d\n",WSAGetLastError());}}else{printf("WSASend 失败 %d\n", WSAGetLastError());}}printf("发送了%d 个字节\n", sendedBytes);WSACloseEvent(evobj);closesocket(HSocket);WSACleanup();return 0;
}

recvicer程序

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable : 4996)
#define BUFFER_SIZE 1024
int main(int argc, char* argv[])
{WSADATA initsock;if (WSAStartup(MAKEWORD(2, 2), &initsock) != 0){printf("WSAStartup失败		");return -1;}//创建重叠模型套接字SOCKET s = WSASocket(PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);if (s == INVALID_SOCKET){printf("socket失败");return -1;}
#pragma region 经典起手式 设置端口和ip 并绑定服务器套接字,进入监听,并允许连接//设置ip和端口sockaddr_in servAddr;servAddr.sin_family = AF_INET;servAddr.sin_port = htons(4567);servAddr.sin_addr.S_un.S_addr = INADDR_ANY;//绑定套接字if (bind(s, (LPSOCKADDR)&servAddr, sizeof(servAddr)) == SOCKET_ERROR){printf("bind失败");closesocket(s);WSACleanup();return -1;}//进入监听if (listen(s, 5) == SOCKET_ERROR){printf("listen失败%d\n",WSAGetLastError());closesocket(s);WSACleanup();return -1;}sockaddr_in clintAddr;int lenOfclintAddr= sizeof(clintAddr);SOCKET hClintSock = accept(s, (LPSOCKADDR)&clintAddr, &lenOfclintAddr);if (hClintSock == INVALID_SOCKET){printf("accept失败%d\n", WSAGetLastError());closesocket(s);WSACleanup();return -1;}
#pragma endregion//创建手动重置初始无信号的事件对象,将地址保存到OVERLAPPED结构变量中WSAEVENT evObj = WSACreateEvent();OVERLAPPED overlapped;memset(&overlapped, 0, sizeof(overlapped));overlapped.hEvent = evObj;//保存数据的缓冲区WSABUF dataBuf;char buf[BUFFER_SIZE] = { 0 };dataBuf.len = BUFFER_SIZE;dataBuf.buf = buf;//WSARecv函数返回时,接收的数据字节数DWORD recvBytes = 0;//传输特性 DWORD flags = 0;if (WSARecv(hClintSock, &dataBuf, 1, &recvBytes, &flags, &overlapped, NULL) == SOCKET_ERROR){if (WSAGetLastError() == WSA_IO_PENDING){puts("后台接收数据中");WSAWaitForMultipleEvents(1, &evObj, true, WSA_INFINITE, false);WSAGetOverlappedResult(hClintSock, &overlapped, &recvBytes, FALSE, NULL);}else{printf("WSARecv失败%d\n", WSAGetLastError());WSACloseEvent(evObj);closesocket(s);WSACleanup();return -1;}}printf("接收到消息:%s\n", buf);WSACloseEvent(evObj);closesocket(s);WSACleanup();return 0;
}

基于apc的回调函数通知io完成 的recvicer

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable : 4996)
#define BUFFER_SIZE 1024
//WSARecv函数返回时,接收的数据字节数
DWORD g_recvBytes = 0;
char g_buf[BUFFER_SIZE];
void  CompRoutine(IN DWORD dwError,IN DWORD cbTransferred,IN LPWSAOVERLAPPED lpOverlapped,IN DWORD dwFlags
);
int main(int argc, char* argv[])
{WSADATA initsock;if (WSAStartup(MAKEWORD(2, 2), &initsock) != 0){printf("WSAStartup失败		");system("pause");return -1;}//创建重叠模型套接字SOCKET s = WSASocket(PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);if (s == INVALID_SOCKET){printf("socket失败");system("pause");return -1;}
#pragma region 经典起手式 设置端口和ip 并绑定服务器套接字,进入监听,并允许连接//设置ip和端口sockaddr_in servAddr;servAddr.sin_family = AF_INET;servAddr.sin_port = htons(4567);servAddr.sin_addr.S_un.S_addr = INADDR_ANY;//绑定套接字if (bind(s, (LPSOCKADDR)&servAddr, sizeof(servAddr)) == SOCKET_ERROR){printf("bind失败");closesocket(s);WSACleanup();system("pause");return -1;}//进入监听if (listen(s, 5) == SOCKET_ERROR){printf("listen失败%d\n", WSAGetLastError());closesocket(s);WSACleanup();system("pause");return -1;}sockaddr_in clintAddr;int lenOfclintAddr = sizeof(clintAddr);SOCKET hClintSock = accept(s, (LPSOCKADDR)&clintAddr, &lenOfclintAddr);if (hClintSock == INVALID_SOCKET){printf("accept失败%d\n", WSAGetLastError());closesocket(s);WSACleanup();system("pause");return -1;}
#pragma endregion//这个事件只是为了让当前线程进入可警报状态WSAEVENT evObj = WSACreateEvent();OVERLAPPED overlapped;memset(&overlapped, 0, sizeof(overlapped));//保存数据的缓冲区WSABUF dataBuf;dataBuf.len = BUFFER_SIZE;dataBuf.buf = g_buf;//传输特性 DWORD flags = 0;if (WSARecv(hClintSock, &dataBuf, 1, &g_recvBytes, &flags, &overlapped,(LPWSAOVERLAPPED_COMPLETION_ROUTINE)CompRoutine) == SOCKET_ERROR){if (WSAGetLastError() == WSA_IO_PENDING){puts("后台接收数据中");}}//只是为了假装自己进入了等待状态,,,,,APC函数将唤醒 这个线程//因为我在等待/*DWORD ret=WSAWaitForMultipleEvents(1, &evObj, FALSE, WSA_INFINITE, TRUE);if (ret == WAIT_IO_COMPLETION){printf("io传输已完成");}*/DWORD ret = SleepEx(INFINITE, TRUE);if (ret == WAIT_IO_COMPLETION){printf("io传输已完成");}WSACloseEvent(evObj);closesocket(s);WSACleanup();system("pause");return 0;
}
//本程序  将会由于调用约定错误  而引发c0005异常
// vs中设置的调用约定默认为 __cdecl (/Gd)
void  CompRoutine(IN DWORD dwError,IN DWORD cbTransferred,IN LPWSAOVERLAPPED lpOverlapped,IN DWORD dwFlags
)
{if (dwError!=0){printf("完成回调函数失败\n");}else{g_recvBytes = cbTransferred;printf("接收到的消息:%s",g_buf);}
}

相关文章:

<winsock>重叠IO模型

基于事件判断io完成 send程序 #include <stdio.h> #include <winsock2.h>#pragma comment(lib, "Ws2_32.lib") #pragma warning(disable : 4996)int main() {WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) ! 0){printf("WSAStart…...

Android Tools | 如何使用Draw.io助力Android开发:从UI设计到流程优化

Android Tools | 如何使用Draw.io助力Android开发&#xff1a;从UI设计到流程优化 1. 引言 在Android开发中&#xff0c;视觉化设计与流程管理至关重要。虽然开发工具如Android Studio强大&#xff0c;但它并不适用于所有设计场景。Draw.io是一款免费的在线绘图工具&#xff…...

Java 每日一刊(第5期):变量守护者

前言 这里是分享 Java 相关内容的专刊&#xff0c;每日一更。 本期将为大家带来以下内容&#xff1a; 量子数据宇宙的变量守护者第一章&#xff1a;能源错配与基本数据类型第二章&#xff1a;引用类型与通讯网络的崩溃第三章&#xff1a;作用域冲突与系统崩溃终章&#xff1…...

【C++二分查找】2517. 礼盒的最大甜蜜度

本文涉及的基础知识点 C二分查找 贪心&#xff08;决策包容性) LeetCode 2517. 礼盒的最大甜蜜度 给你一个正整数数组 price &#xff0c;其中 price[i] 表示第 i 类糖果的价格&#xff0c;另给你一个正整数 k 。 商店组合 k 类 不同 糖果打包成礼盒出售。礼盒的 甜蜜度 是礼…...

【详解】数据库E-R图——医院计算机管理系统

题目 某医院病房计算机管理中需要如下信息&#xff1a; 科室&#xff1a;科室名&#xff0c;科室地址&#xff0c;科室电话&#xff0c;医生姓名 病房&#xff1a;病房号&#xff0c;床位号&#xff0c;所属科室名 医生&#xff1a;工作证号&#xff0c;姓名&#xff0c;性别&a…...

分类预测|基于改进的灰狼IGWO优化支持向量机SVM的数据分类预测matlab程序 改进策略:Cat混沌与高斯变异

分类预测|基于改进的灰狼IGWO优化支持向量机SVM的数据分类预测matlab程序 改进策略&#xff1a;Cat混沌与高斯变异 文章目录 一、基本原理原理流程1. **定义目标函数**2. **初始化GWO**3. **评估适应度**4. **更新狼的位置**5. **更新狼的等级**6. **重复迭代**7. **选择最佳解…...

圆锥曲线练习

设 A ( x 1 , y 1 ) , B ( x 2 , y 2 ) A\left( x_{1}, y_{1} \right), B\left( x_{2}, y_{2} \right) A(x1​,y1​),B(x2​,y2​) l : y k ( x 2 ) l: y k\left( x2 \right) l:yk(x2) 显然 y 0 y0 y0符合题意 当 k ≠ 0 k\neq 0 k0 联立 l l l和 C C C ( k 2 1 2 ) x…...

STM32时钟树

1 什么是时钟 2 时钟数简图...

NX—UI界面生成的文件在VS上的设置

UI界面保存生成的三个文件 打开VS创建项目&#xff0c;删除自动生成的cpp文件&#xff0c;将生成的hpp和cpp文件拷贝到项目的目录下&#xff0c;并且在VS项目中添加现有项目。 修改VS的输出路径&#xff0c;项目右键选择属性&#xff0c;链接器中的常规&#xff0c;文件路径D:…...

Wine容器内程序执行sh脚本问题研究

问题背景 wpf程序在wine环境执行sh脚本&#xff0c;不能等待脚本执行完成自动退出的问题进行了研究&#xff0c;需求很简单&#xff0c;在wpf程序使用cmd&#xff0c;或者bat &#xff0c;又或者是直接执行sh脚本&#xff0c;想到脚本执行完成才处理后面的逻辑。但是实际验证过…...

《深度学习》OpenCV轮廓检测 模版匹配 解析及实现

目录 一、模型匹配 1、什么是模型匹配 2、步骤 1&#xff09;提取模型的特征 2&#xff09;在图像中查找特征点 3&#xff09;进行特征匹配 4&#xff09;模型匹配 3、参数及用法 1、用法 2、参数 1&#xff09;image&#xff1a;待搜索对象 2&#xff09;templ&am…...

Java XML

1、XML文件介绍 配置文件&#xff1a;用来保存设置的一些东西。 拿IDEA来举例&#xff0c;比如设置的背景图片&#xff0c;字体信息&#xff0c;字号信息和主题信息等等。 &#xff08;1&#xff09;以前是用txt保存的&#xff0c;没有任何优点&#xff0c;而且不利于阅读&a…...

好用的视频压缩工具有哪些?这4款千万不要错过

视频压缩的方法有很多种&#xff0c;像我们手机里的视频剪辑工具&#xff0c;手机和电脑自带的压缩功能&#xff0c;在线压缩网站&#xff0c;专业压缩软件压缩等等。不同的场景和需求下大家可以选择不同的工具&#xff0c;但是如果碰到需要大量和经常压缩视频的话&#xff0c;…...

【Python爬虫系列】_016.关于登录和验证码

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…...

基于opencv实现双目立体匹配点云距离

双目相机或两个单目相机。 一、相机标定 MATLAB软件&#xff0c;打开双目标定app。 点击add images&#xff0c;弹出加载图像的窗口&#xff0c;分别导入左图和右图&#xff0c;设置黑白格长度&#xff08;标定板的长度一般为20&#xff09;。 点击确定&#xff0c;弹出加载…...

RabbitMQ高级篇,进阶内容

强烈建议在看本篇博客之前快速浏览文章&#xff1a;RabbitMQ基础有这一篇就够了 RabbitMQ高级篇 0. 前言1. 发送者的可靠性1.1 生产者重试机制1.2 生产者确认机制1.3 实现生产者确认 2. MQ的可靠性2.1 MQ持久化2.2 LazyQueue 3. 消费者的可靠性3.1 消费者确认机制3.2 失败重试策…...

STM32重定义printf,实现串口打印

在“usart.c”文件中加入以下代码 #ifdef __GNUC__#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endifPUTCHAR_PROTOTYPE{HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);return ch; }…...

项目进度

变为负进度了&#xff0c;还是要用baseservlet&#xff0c;我就又重新写了一部分&#xff0c;看了好几遍视频&#xff0c;突然就想明白了&#xff0c;感觉每次要上课&#xff0c;就时间不连续思路总是断&#xff0c;今天晚自习算是搞懂了怎么写了&#xff0c;就是代码有点多&am…...

Android的内核

Android的内核是基于Linux的长期支持版本的“Android通用内核(ACK)”。 Android作为一个广泛使用的操作系统&#xff0c;其根基在于内核的设计和功能。下面将深入探讨Android内核的各个方面&#xff0c;从其基本结构到与Linux内核的关系&#xff0c;再到内核的版本管理及在设备…...

Github Wiki 超链接 转 码云Gitee Wiki 超链接

Github Wiki 超链接 转 码云Gitee Wiki 超链接 Github 是 &#xff1a;[[相对路径]] Gitee 是 &#xff1a;[链接文字](./相对路径) 查找&#xff1a;\[\[(.*?)\]\] 替换&#xff1a;[$1]\(./$1\) 或替换&#xff1a;**[$1]\(./$1\)** &#xff08;码云的超链接&#xff0c;很…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...