#include <WINSOCK2.H>
#include <stdio.h> #define PORT 5150
#define MSGSIZE 1024 #pragma comment(lib, "ws2_32.lib") typedef struct
{
WSAOVERLAPPED overlap;
WSABUF Buffer;
char szMessage[MSGSIZE];
DWORD NumberOfBytesRecvd;
DWORD Flags;
SOCKET sClient;
}PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA; DWORD WINAPI WorkerThread(LPVOID);
void CALLBACK CompletionROUTINE(DWORD, DWORD, LPWSAOVERLAPPED, DWORD); SOCKET g_sNewClientConnection;
BOOL g_bNewConnectionArrived = FALSE; int main()
{
WSADATA wsaData;
SOCKET sListen;
SOCKADDR_IN local, client;
DWORD dwThreadId;
int iaddrSize = sizeof(SOCKADDR_IN); // Initialize Windows Socket library
WSAStartup(0x0202, &wsaData); // Create listening socket
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Bind
local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(PORT);
bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN)); // Listen
listen(sListen, ); // Create worker thread
CreateThread(NULL, , WorkerThread, NULL, , &dwThreadId); while (TRUE)
{
// Accept a connection
g_sNewClientConnection = accept(sListen, (struct sockaddr *)&client, &iaddrSize);
g_bNewConnectionArrived = TRUE;
printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
}
} DWORD WINAPI WorkerThread(LPVOID lpParam)
{
LPPER_IO_OPERATION_DATA lpPerIOData = NULL; while (TRUE)
{
if (g_bNewConnectionArrived)
{
// Launch an asynchronous operation for new arrived connection
lpPerIOData = (LPPER_IO_OPERATION_DATA)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(PER_IO_OPERATION_DATA));
lpPerIOData->Buffer.len = MSGSIZE;
lpPerIOData->Buffer.buf = lpPerIOData->szMessage;
lpPerIOData->sClient = g_sNewClientConnection; WSARecv(lpPerIOData->sClient,
&lpPerIOData->Buffer,
,
&lpPerIOData->NumberOfBytesRecvd,
&lpPerIOData->Flags,
&lpPerIOData->overlap,
CompletionROUTINE); g_bNewConnectionArrived = FALSE;
} SleepEx(, TRUE);                  //这里如果不sleep,根本不会进入完成例程的回调,第一个参数时间可以适当缩小
}
return ;
} void CALLBACK CompletionROUTINE(DWORD dwError,
DWORD cbTransferred,
LPWSAOVERLAPPED lpOverlapped,
DWORD dwFlags)
{
LPPER_IO_OPERATION_DATA lpPerIOData = (LPPER_IO_OPERATION_DATA)lpOverlapped;   if (dwError != || cbTransferred == )
  {
  // Connection was closed by client
  closesocket(lpPerIOData->sClient);
  HeapFree(GetProcessHeap(), , lpPerIOData);
  }
  else
{
lpPerIOData->szMessage[cbTransferred] = '\0';
send(lpPerIOData->sClient, lpPerIOData->szMessage, cbTransferred, ); // Launch another asynchronous operation
memset(&lpPerIOData->overlap, , sizeof(WSAOVERLAPPED));
lpPerIOData->Buffer.len = MSGSIZE;
lpPerIOData->Buffer.buf = lpPerIOData->szMessage; WSARecv(lpPerIOData->sClient,
&lpPerIOData->Buffer,
,
&lpPerIOData->NumberOfBytesRecvd,
&lpPerIOData->Flags,
&lpPerIOData->overlap,
CompletionROUTINE);
}
}

这个模型中有两个函数可以交换着用,那就是WSAWaitForMultipleEvents()和SleepEx()函数,前者需要一个事件驱动,后者则不需要。是不是听起来后者比较厉害,当然不是,简单肯定是拿某种性能换来的,那就是当多client同时发出请求的时候,SleepEx如果等候时间设置成比较大的话,会造成client连接不上的现象。具体可以运行一下示例代码体会一下。

完成例程来实现重叠I/O比用事件通知简单得多。在这个模型中,主线程只用不停的接受连接即可;辅助线程判断有没有新的客户端连接被建立,如果有,就为那个客户端套接字激活一个异步的WSARecv操作,然后调用SleepEx使线程处于一种可警告的等待状态,以使得I/O完成后CompletionROUTINE可以被内核调用。如果辅助线程不调用SleepEx,则内核在完成一次I/O操作后,无法调用完成例程(因为完成例程的运行应该和当初激活WSARecv异步操作的代码在同一个线程之内)。

完成例程内的实现代码比较简单,它取出接收到的数据,然后将数据原封不动的发送给客户端,最后重新激活另一个WSARecv异步操作。注意,在这里用到了“尾随数据”。我们在调用WSARecv的时候,参数lpOverlapped实际上指向一个比它大得多的结构PER_IO_OPERATION_DATA,这个结构除了WSAOVERLAPPED以外,还被我们附加了缓冲区的结构信息,另外还包括客户端套接字等重要的信息。这样,在完成例程中通过参数lpOverlapped拿到的不仅仅是WSAOVERLAPPED结构,还有后边尾随的包含客户端套接字和接收数据缓冲区等重要信息。这样的C语言技巧在我后面介绍完成端口的时候还会使用到。

windows网络模型之重叠IO(完成例程)的使用的更多相关文章

  1. windows网络模型之重叠IO的使用

    大部分内容转载自https://blog.csdn.net/piggyxp/article/details/114883 目录: 1. 重叠模型的优点 2. 重叠模型的基本原理 3. 关于重叠模型的基 ...

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

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

  3. winSocket编程(九)重叠IO

    重叠模型的优点 重叠模型的基本原理 关于重叠模型的基础知识 重叠模型的实现步骤 多客户端情况的注意事项 一.重叠模型的优点 1.可以运行在支持Winsock2的所有Windows平台 ,而不像完成端口 ...

  4. 重叠IO

    一. 异步IO        说到重叠模型首先还是提一下异步IO比较好,因为从本质上讲,重叠模型也是一种异步IO模型.       我们知道,相对于计算机执行的其他操作而言,设备IO(文件.管道.套接 ...

  5. 重叠io操作

    第一章 一. 重叠模型的优点 1. 可以运行在支持Winsock2的所有Windows平台 ,而不像完成端口只是支持NT系统. 2. 比起阻塞.select.WSAAsyncSelect以及WSAEv ...

  6. windows网络模型

    Windows提供了四种异步IO技术,机制几乎时相同的,区别在于通知结果的方式不同: 1.通过注册的消息函数进行通知 2.通过内核event事件进行通知 3.通过称为完成例程的回调函数进行通知 4.通 ...

  7. Windows内核原理-同步IO与异步IO

    目录 Windows内核原理-同步IO与异步IO 背景 目的 I/O 同步I/O 异步I/O I/O完成通知 总结 参考文档 Windows内核原理-同步IO与异步IO 背景 在前段时间检查异常连接导 ...

  8. 重叠IO 模型

    1. 重叠模型的优点 2. 重叠模型的基本原理 3. 关于重叠模型的基础知识 4. 重叠模型的实现步骤 5. 多客户端情况的注意事项 一.重叠模型的优点   1.可以运行在支持Winsock2的所有W ...

  9. Socket重叠IO

    1.为什么到现在才弄懂这个 不知道这个Socket重叠IO这种模型是不是socket IO完成端口的基础,不过我感觉,学习一下这个再去学习socket IO完成端口是比较有好处的. 这个Scoket重 ...

随机推荐

  1. 【实战】SSL和TLS漏洞验证

    工具下载:git clone https://github.com/drwetter/testssl.sh.git 实验环境:192.168.1.22(bee-box v1.6) 192.168.1. ...

  2. sed命令——批量修改文件内容

    批量替换单个文件内容 命令格式:sed -i 's/旧内容/新内容/g' 文件路径 sed -i 's/oldString/newString/g' file 例如:我想替换cwx.txt文件中的 j ...

  3. (转)裸奔的后果!一次ssh被篡改的入侵事件

    裸奔的后果!一次ssh被篡改的入侵事件 原文:http://blog.51cto.com/phenixikki/1546669 通常服务器安全问题在规模较小的公司常常被忽略,没有负责安全的专员,尤其是 ...

  4. org.hibernate.QueryException: duplicate alias: r hibernate别名重复问题解决

    今天做项目的过程中发现,多表查询的时候如果使用hibernate的DetachedCriteria离线查询方式的时候, 在多表关联的时候我们需要使用别名的方式去实现. 但是代码运行的过程中抛出了下面的 ...

  5. 新建maven工程index.jsp页面报错

    引入servlet依赖jar <dependency><groupId>javax.servlet</groupId><artifactId>servl ...

  6. java使用POI进行 Excel文件解析

    package com.timevale.esign.vip.util; import java.io.File; import java.io.FileInputStream; import jav ...

  7. FZU 1921——栀子花开——————【线段树单点更新】

    栀子花开 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status  ...

  8. 操作系统管理CPU的直观想法

    CPU的工作原理 要想管理CPU,就要先学会如何使用CPU.我们先从一个程序的执行来看看CPU是如何工作的. void main(){ int i , sum; ; i < ; i++){ su ...

  9. bzoj 4771: 七彩树

    Description 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节 点的颜色为c[i].如果c[i]=c[j],那么我们认为点i和点j拥有 ...

  10. [转]微信小程序(应用号)是什么,是否值得投入进来做?

    本文转自:http://www.woshipm.com/it/417887.html 距离张小龙的那场首次公开演讲已经有九个月了,而在那场演讲中备受关注的「应用号」在千呼万唤中终于以「小程序」的名字正 ...