重叠I/O就相当于异步I/O。

一、重叠I/O的I/O完成确认

1、使用事件对象

接收端:

 #include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h> #define BUF_SIZE 1024
void ErrorHandling(char *message); int main(int argc, char *argv[])
{
if (argc != ) {
printf("Usage : %s <port>\n", argv[]);
exit();
} WSADATA wsaData;
SOCKET hLinSock, hCRecvSock;
SOCKADDR_IN lisnAdr, recvAdr;
int recvAdrSz; WSABUF dataBuf;
WSAEVENT evObj;
WSAOVERLAPPED overlapped; char buf[BUF_SIZE];
int recvBytes = , flags = ; if (WSAStartup(MAKEWORD(, ), &wsaData) != )
ErrorHandling("WSAStartup() error."); hLinSock = socket(PF_INET, SOCK_STREAM, );
memset(&lisnAdr, , sizeof(lisnAdr));
lisnAdr.sin_family = AF_INET;
lisnAdr.sin_addr.s_addr = htonl(INADDR_ANY);
lisnAdr.sin_port = htons(atoi(argv[])); if (bind(hLinSock, (SOCKADDR*)&lisnAdr, sizeof(lisnAdr)) == SOCKET_ERROR)
ErrorHandling("bind() error.");
if (listen(hLinSock, ) == SOCKET_ERROR)
ErrorHandling("listen() error."); recvAdrSz = sizeof(recvAdr);
hCRecvSock = accept(hLinSock, (SOCKADDR*)&recvAdr, &recvAdrSz); evObj = WSACreateEvent();
memset(&overlapped, , sizeof(overlapped));
overlapped.hEvent = evObj;
dataBuf.len = BUF_SIZE;
dataBuf.buf = buf; if (WSARecv(hCRecvSock, &dataBuf, , (LPDWORD)&recvBytes, (LPDWORD)&flags, &overlapped, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() == WSA_IO_PENDING)
{
puts("Background data receive");
WSAWaitForMultipleEvents(, &evObj, TRUE, WSA_INFINITE, FALSE);
WSAGetOverlappedResult(hCRecvSock, &overlapped, (LPDWORD)&recvBytes, FALSE, NULL);
}
else{
ErrorHandling("WSARECV() error");
}
} printf("Received message: %s\n", buf);
WSACloseEvent(evObj);
closesocket(hCRecvSock);
closesocket(hLinSock);
WSACleanup();
return ;
} void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
} void CompressSockets(SOCKET hSockArr[], int idx, int total){
for (int i = idx; i < total; i++)
hSockArr[i] = hSockArr[i + ];
} void CompressEvents(WSAEVENT hEventArr[], int idx, int total){
for (int i = idx; i < total; i++)
hEventArr[i] = hEventArr[i + ];
}

发送端:

 #pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h> void ErrorHandling(char *message); int main(int argc, char* argv[]) {
if (argc != ) {
printf("Usage : %s <IP> <port>\n", argv[]);
exit();
} WSADATA wsaData;
SOCKET hSocket;
SOCKADDR_IN sendAdr; WSABUF dataBuf;
char msg[] = "Network is Computer!";
int sendBytes = ; WSAEVENT evObj;
WSAOVERLAPPED overlapped; if (WSAStartup(MAKEWORD(, ), &wsaData) != )
ErrorHandling("WSAStartup() error"); hSocket = WSASocket(PF_INET, SOCK_STREAM, , NULL, , WSA_FLAG_OVERLAPPED);
memset(&sendAdr, , sizeof(sendAdr));
sendAdr.sin_family = AF_INET;
sendAdr.sin_addr.s_addr = inet_addr(argv[]);
sendAdr.sin_port = htons(atoi(argv[])); if (connect(hSocket, (SOCKADDR*)&sendAdr, sizeof(sendAdr)) == SOCKET_ERROR)
ErrorHandling("connect() error");
else
printf("Connected.......\n"); evObj = WSACreateEvent();
memset(&overlapped, , sizeof(overlapped));
overlapped.hEvent = evObj;
dataBuf.len = strlen(msg) + ;
dataBuf.buf = msg; if (WSASend(hSocket, &dataBuf, , (LPDWORD)&sendBytes, , &overlapped, NULL) == SOCKET_ERROR){
if (WSAGetLastError() == WSA_IO_PENDING){
puts("Background data send");
WSAWaitForMultipleEvents(, &evObj, TRUE, WSA_INFINITE, FALSE);
WSAGetOverlappedResult(hSocket, &overlapped, (LPDWORD)&sendBytes, FALSE, NULL);
}
else{
ErrorHandling("WSASend() error");
}
}
printf("Send data size:%d\n", sendBytes);
WSACloseEvent(evObj);
closesocket(hSocket);
WSACleanup();
return ;
} void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
}

2、基于Completion Routine

接收端:

 #include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h> #define BUF_SIZE 1024
void ErrorHandling(char *message);
void CALLBACK CompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD); WSABUF dataBuf;
char buf[BUF_SIZE];
int recvBytes = ; int main(int argc, char *argv[])
{
if (argc != ) {
printf("Usage : %s <port>\n", argv[]);
exit();
} WSADATA wsaData;
SOCKET hLinSock, hRecvSock;
SOCKADDR_IN lisnAdr, recvAdr; WSAEVENT evObj;
WSAOVERLAPPED overlapped; int idx, recvAdrSz, flags = ; if (WSAStartup(MAKEWORD(, ), &wsaData) != )
ErrorHandling("WSAStartup() error."); hLinSock = socket(PF_INET, SOCK_STREAM, );
memset(&lisnAdr, , sizeof(lisnAdr));
lisnAdr.sin_family = AF_INET;
lisnAdr.sin_addr.s_addr = htonl(INADDR_ANY);
lisnAdr.sin_port = htons(atoi(argv[])); if (bind(hLinSock, (SOCKADDR*)&lisnAdr, sizeof(lisnAdr)) == SOCKET_ERROR)
ErrorHandling("bind() error.");
if (listen(hLinSock, ) == SOCKET_ERROR)
ErrorHandling("listen() error."); recvAdrSz = sizeof(recvAdr);
hRecvSock = accept(hLinSock, (SOCKADDR*)&recvAdr, &recvAdrSz);
if (hRecvSock == INVALID_SOCKET)
ErrorHandling("accept() error"); memset(&overlapped, , sizeof(overlapped)); dataBuf.len = BUF_SIZE;
dataBuf.buf = buf; evObj = WSACreateEvent(); if (WSARecv(hRecvSock, &dataBuf, , (LPDWORD)&recvBytes, (LPDWORD)&flags, &overlapped, CompRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() == WSA_IO_PENDING)
{
puts("Background data receive");
}
else{
ErrorHandling("WSARECV() error");
}
} idx = WSAWaitForMultipleEvents(, &evObj, FALSE, WSA_INFINITE, TRUE);
if (idx == WAIT_IO_COMPLETION)
puts("Overlapped I/O Completed");
else
ErrorHandling("WSARecv() error");
WSACloseEvent(evObj);
closesocket(hRecvSock);
closesocket(hLinSock);
WSACleanup();
return ;
} void CALLBACK CompRoutine(DWORD dwError, DWORD szRecvBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags){ if (dwError != ){
ErrorHandling("CompRoutine error");
}
else{
recvBytes = szRecvBytes;
printf("Received message: %s\n", buf);
}
} void ErrorHandling(char *message) {
fputs(message, stderr);
fputc('\n', stderr);
}

发送端:同上

windows重叠I/O模型的更多相关文章

  1. c++ 网络编程(十) LINUX/windows 异步通知I/O模型与重叠I/O模型 附带示例代码

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9662931.html 一.异步IO模型(asynchronous IO) (1)什么是异步I/ ...

  2. windows 异步通知I/O模型与重叠I/O模型

    一.异步IO模型(asynchronous IO) (1)什么是异步I/O 异步I/O(asynchronous I/O)由POSIX规范定义.演变成当前POSIX规范的各种早起标准所定义的实时函数中 ...

  3. 重叠I/O模型

    一. 重叠I/O的概念当调用ReadFile和WriteFile时,如果最后一个参数lpOverlapped设置为NULL,那么线程就阻塞在这里,直到读写完指定的数据后,它们才返回.这样在读写大文件的 ...

  4. 用完成例程(Completion Routine)实现的重叠I/O模型

    /// 用完成例程(Completion Routine)实现的重叠I/O模型 /// 异步IO模型 /// 用完成例程来实现重叠I/O比用事件通知简单得多.在这个模型中,主线程只用不停的接受连接 / ...

  5. Windows五种IO模型性能分析和Linux五种IO模型性能分析

    Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blo ...

  6. Windows socket I/O模型 之 select(2)

    在Windows socket I/O模型 之  select(1)中.我们仅仅是在console中简单的模拟了select的处理方法. 还有非常多特性不能改动.比方仅仅能写,不能读. 没使用线程.也 ...

  7. 关于Windows下的访问控制模型

    在探索Windows操作系统的过程中,发现很多有意思 的东西. Windows下的访问控制模型也是我在Github上浏览代码时,无意中发现的. 项目地址 https://github.com/Krut ...

  8. Linux与Windows的设备驱动模型对比

    Linux与Windows的设备驱动模型对比 名词缩写: API 应用程序接口(Application Program Interface ) ABI 应用系统二进制接口(Application Bi ...

  9. 四.Windows I/O模型之重叠IO(overlapped)模型

    1.适用于除Windows CE之外的各种Windows平台.在使用这个模型之前应该确保该系统安装了Winsock2.重叠模型的基本设计原理是使用一个重叠的数据结构,一次投递一个或多个Winsock ...

随机推荐

  1. Linux Spi驱动移植小结

    2012-01-07 22:21:29 效果图: 理论学习后,主要是linux中spi子系统设备框架的了解后,主控制器与设备分离的思想,那么我要开始动手了. 1,  make menuconfig添加 ...

  2. 【.NET】 C# 时间戳和DataTime 互相转换

    1.C# DateTime转换为Unix时间戳 System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(, , )); // ...

  3. 问题 1690: 算法4-7:KMP算法中的模式串移动数组

    题目链接:https://www.dotcpp.com/oj/problem1690.html 题目描述 字符串的子串定位称为模式匹配,模式匹配可以有多种方法.简单的算法可以使用两重嵌套循环,时间复杂 ...

  4. 常用VIM插件配置

    airline 状态栏美化 除了airline本体还要下airline主题 和打过powerline补丁的字体 常用设置: set laststatus=2 " 总是显示状态栏 set no ...

  5. vscode技巧之代码规范editorconfig

    使用代码片段一键初始化editorconfig样式 第一步,选择文件 第二步,在首选项中选择代码片段 第三步,搜索框中键入properties,并enter键选择进入该文件 第四步,键入下面的代码 { ...

  6. Elasticsearch NEST 控制字段名称命名格式

    在使用NEST操作elasticsearch时,字段名会根据model中字段,默认为首字母小写. 如果需要调整NEST的默认明个规则,可以在 ConnectionSettings中进行自定义. var ...

  7. 关于win10环境下Anaconda python,用pip安装包及升级时SSL报错的问题

    刚开始查完以为是网的问题,但是添加信任值\镜像网站\手动下载安装都失败了. 检查后发现python中无SSL模块,检查Anaconda后发现是少加了环境变量Anaconda3\Library\bin, ...

  8. parquet列式文件实战(未完,待续)

    parquet列式文件实战 parquet code demo http://www.programcreek.com/java-api-examples/index.php?source_dir=h ...

  9. Python+MapReduce实现矩阵相乘

    算法原理 map阶段 在map阶段,需要做的是进行数据准备.把来自矩阵A的元素aij,标识成p条<key, value>的形式,key="i,k",(其中k=1,2,. ...

  10. android 百度地图 定位获取位置失败 62错误

    一切正常步骤进行但是还是没有获得定位,得到的坐标总是49E.xxxx,错误代码总是62 总是以为代码.或jar包.或还有什么权限没给.搞了好久,十分郁闷.在控制台上又没有什么具体的错误提示 经过无数次 ...