重叠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. 介绍Kubernetes监控Heapster

    什么是Heapster? Heapster是容器集群监控和性能分析工具,天然的支持Kubernetes和CoreOS,Kubernetes有个出名的监控agent—cAdvisor.在每个kubern ...

  2. 5.JAVA基础复习——JAVA中的static关键字作用与用法

    static关键字: 特点: 1.static是一个修饰符,用于修饰成员.(成员变量,成员函数)static修饰的成员变量 称之为静态变量或类变量. 2.static修饰的成员被所有的对象共享. 3. ...

  3. JSON.parse(JSON.stringify(obj))

    JSON.parse(JSON.stringify(obj)实现数组的深拷贝 利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象

  4. 【Diary】

    [写日记是好习惯] 前记 很随意的日记.想什么写什么,没有限制. 希望以后看到曾经,努力的自己比摸鱼的自己多. 2019.3 2019.3.29 第24次请假打卡 xzh:那些理科男以后都会当IT工作 ...

  5. varnish 测试

    安装 通过epel 源 yum 安装 [root@localhost varnish]# rpm -ql varnish /etc/logrotate.d/varnish /etc/varnish / ...

  6. Excel 如何判断某列哪些单元格包含某些字符

    “条件格式”,公式: =IF(COUNTIF($A2,,,) 然后根据需要设置格式

  7. Exp3 免杀原理与实践 20164303 景圣

    Exp3 免杀原理与实践 一.实验内容 1. 正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用shellcode编程等免杀工具或技巧 2. 通过组合 ...

  8. Django回顾

    Django简介 Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 半成品自定义we ...

  9. android开发_Eclipse新建项目+新建模拟器

    一.新建项目 1 Eclipse->右键->new->Android Application Project,得到下图: 2 输入创建项目信息 3 点击next 4 点击 next ...

  10. python脚本练习之编译安装python

    练习 py-shelll #coding=utf-8 import os,sys if os.getuid() == 0: pass else: print('当前用户不是root,请以root用户执 ...