windows重叠I/O模型
重叠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模型的更多相关文章
- c++ 网络编程(十) LINUX/windows 异步通知I/O模型与重叠I/O模型 附带示例代码
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9662931.html 一.异步IO模型(asynchronous IO) (1)什么是异步I/ ...
- windows 异步通知I/O模型与重叠I/O模型
一.异步IO模型(asynchronous IO) (1)什么是异步I/O 异步I/O(asynchronous I/O)由POSIX规范定义.演变成当前POSIX规范的各种早起标准所定义的实时函数中 ...
- 重叠I/O模型
一. 重叠I/O的概念当调用ReadFile和WriteFile时,如果最后一个参数lpOverlapped设置为NULL,那么线程就阻塞在这里,直到读写完指定的数据后,它们才返回.这样在读写大文件的 ...
- 用完成例程(Completion Routine)实现的重叠I/O模型
/// 用完成例程(Completion Routine)实现的重叠I/O模型 /// 异步IO模型 /// 用完成例程来实现重叠I/O比用事件通知简单得多.在这个模型中,主线程只用不停的接受连接 / ...
- Windows五种IO模型性能分析和Linux五种IO模型性能分析
Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blo ...
- Windows socket I/O模型 之 select(2)
在Windows socket I/O模型 之 select(1)中.我们仅仅是在console中简单的模拟了select的处理方法. 还有非常多特性不能改动.比方仅仅能写,不能读. 没使用线程.也 ...
- 关于Windows下的访问控制模型
在探索Windows操作系统的过程中,发现很多有意思 的东西. Windows下的访问控制模型也是我在Github上浏览代码时,无意中发现的. 项目地址 https://github.com/Krut ...
- Linux与Windows的设备驱动模型对比
Linux与Windows的设备驱动模型对比 名词缩写: API 应用程序接口(Application Program Interface ) ABI 应用系统二进制接口(Application Bi ...
- 四.Windows I/O模型之重叠IO(overlapped)模型
1.适用于除Windows CE之外的各种Windows平台.在使用这个模型之前应该确保该系统安装了Winsock2.重叠模型的基本设计原理是使用一个重叠的数据结构,一次投递一个或多个Winsock ...
随机推荐
- tensorflow学习笔记1:导出和加载模型
用一个非常简单的例子学习导出和加载模型: 导出 写一个y=a*x+b的运算,然后保存graph: import tensorflow as tf from tensorflow.python.fram ...
- 向日葵连CentOS
TeamViewer可以连CentOS,但TeamViewer最近老是提示“检测为商业用途”,5分钟就会自动断,用起来非常不爽,所以决定改用向日葵试下,向日葵目前的口碑也不错,更何况是国产软件,更要支 ...
- 我的web前端整理和学习
知识点收藏:(边看.边记录.边写) 开直播学习:虎牙 待办事理>> 练习自我表达(把文章做成视频).技术学习总结(博客与公众号).跳出舒适圈. 前端知识体系:https://www.cnb ...
- php,js 对字符串按位异或运算加密解密
异或的符号是^.按位异或运算, 对等长二进制模式按位或二进制数的每一位执行逻辑按位异或操作. 操作的结果是如果某位不同则该位为1, 否则该位为0. xor运算的逆运算是它本身,也就是说两次异或同一个数 ...
- golang获取u盘序列号(通过读取注册表实现)
仅供参考 package main import ( "fmt" "log" "os" "strconv" " ...
- 移动web开发中input等输入框问题
移动端web开发时,input等输入框在安卓和iso中都有问题,分别有:1.iso不能点击其他区域使得输入框失去焦点2.iso输入框失去焦点后,键盘产生的空白部分不消失3.安卓端输入框得到焦点后,输入 ...
- 论文笔记:Siamese Cascaded Region Proposal Networks for Real-Time Visual Tracking
Siamese Cascaded Region Proposal Networks for Real-Time Visual Tracking 2019-03-20 16:45:23 Paper:ht ...
- 使用Java SDK实现离线签名
严格来说,tx-signer并不属于SDK,它是bytomd中构建交易.对交易签名两大模块的java实现版.因此,若想用tx-signer对交易进行离线签名,需要由你在本地保管好自己的私钥. 如果你的 ...
- scala链接mysql
方法一:链接并操作mysql //链接Mysqlval driver = "com.mysql.jdbc.Driver"val url = "jdbc:mysql://1 ...
- 意外get接近完美的黑苹果 (UEFI + GPT)
本人大学生一枚,对于高大上的 MAC OS 只能是摸摸口袋 咽咽口水啦.听说黑苹果,就是安装在普通的 pc 上的 MAC系统,那么对应的苹果电脑上的 MAC OS 系统就为白苹果了. 个人也想啃一口黑 ...