重叠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. Caused by: java.lang.NoSuchMethodError: org.apache.poi.hssf.usermodel.HSSFCell.setEncoding(S)V

    java.lang.reflect.InvocationTargetException.  Coused by : java.lang.NoSuchMethodError:这个异常是找不到方法,但是如 ...

  2. [flutter+dart] windows7下开发环境的安装与配置

    前言 博主是做嵌入式的,参加工作时间也不久,而且是非科班出身,之前从未接触过移动开发.最近了解到了flutter框架和dart语言,想作为第二语言学习一下,因此会从最基础的环节开始,以此博客作为记录, ...

  3. workbench使用小笔记(不定期持续更新)

    1. 删除不使用的工作空间 在使用workbench时,之前可能建了好几个工作空间,现在有一些不使用了,每次打开都能还能看到它们,对于强迫症来说多少有一些不爽.如下图: 现在,就把那些不使用的工作空间 ...

  4. 对于react中的this.setState的理解

    一.this.setState第二个参数的作用:修改数据更新后最新的DOM结构 二.this.setState为什么是异步的? 1.setState只在合成事件和钩子函数中是“异步”的,在原生事件和s ...

  5. js中的排序方法

    一.冒泡排序 var  arr=[22,1,33,19,77]; function  bubbleSort(arr){ for(var i=0;i<arr.length-1;i++){ for( ...

  6. iOS进阶之如何进行 HTTP Mock(转载)

    这篇文章会对 OHHTTPStubs 源代码的分析,其实现原理是建立在 NSURLProtocol 的基础上的,对这部分内容不了解的读者,可以阅读这篇文章 iOS 开发中使用 NSURLProtoco ...

  7. java字符串对象存储机制

    String s1="abc";创建了几个String对象 ? String s2 = new String("abc");创建了几个String对象? s1= ...

  8. P1450 [HAOI2008]硬币购物(完全背包+容斥)

    P1450 [HAOI2008]硬币购物 暴力做法:每次询问跑一遍多重背包. 考虑正解 其实每次跑多重背包都有一部分是被重复算的,浪费了大量时间 考虑先做一遍完全背包 算出$f[i]$表示买价值$i$ ...

  9. rem的在vue项目中使用配置,,浏览器的兼容性之Mate标签

    在vue中配置rem 位置:在APP.vue的script中,在export default之外 (()=>{ let winW = document.documentElement.clien ...

  10. d3-tip中show在自己调用时需要改变this值

    <script src="https://d3js.org/d3.v4.min.js"></script><script src="http ...