/////////////////////////////////////////////////
//IOCPDemo.cpp文件调试通过
//I/O完成端口最初的设计是应用程序发出一些异步I/O请求,当这些请求完
//成时,设备驱动把这些工作排序到完成端口,在完成端口等待的线程池
//可以处理这些完成I/O。
//首先调用CreateCompletionPort创建一个完成端口对象。函数的两个功能如下:
//1、创建一个完成端口对象。
//2、将一个或者多个文件句柄(此处是套节字)关联到I/O完成端口对象。
//最初创建时,需要设置的参数是NUMBEROFCONCURRENTTHREADS,它定义了允
//许在完成端口上同时执行的线程的数量。为0表示允许线程数量与处理器数
//量一样多。
//CreateIoCompletionPort函数的NumberOfConcurrentThreads参数个线程允
//许运行,即使创建了比允许线程更多的工作线程,仍只有允许线程数进
//入线程池。但是有时候,确实需要创建更多的线程,因为某个
//线程调用了一个函数,进行了暂停状态,体眠后暂时不能为线程池所有。所以
//必须有新的工作线程来补充。
//有了足够的线程来处理完成端口上的I/O请求之后,就该为完成端口关联套
//节字句柄,向完成端口关联套节字句柄之后,便可以通过在套节字上投递重叠
//发送和接收请求处理I/O,在这些I/O操作完成时,I/O系统会向完成端口对
//象发送一个完成通知封包。应用程序使用GetQueuedCompletionStatus函数
//可以取得这些队列中的封包,返回后说明发生了如下事件之一:
//1、GetQueuedCompletionStatus调用失败,说明在此套节字上有错误发生。
//2、BytesTransferred为0说明套节字被对方关闭。
//3、I/O请求成功完成。通过per-I/O数据中的OperationType域查看哪个I/O
//请求完成了。
//在每个套节字句柄关闭,通过PostQueuedCompletionStatus向工作线程发
//送特定的完成封包终止完成端口上处理的I/O线程,
#include "../common/initsock.h"
#include <stdio.h>
#include <windows.h>
// 初始化Winsock库
CInitSock theSock;
#define BUFFER_SIZE 1024
typedef struct_PER_HANDLE_DATA//per-handle数据
{
SOCKETs;//对应的套节字句柄
sockaddr_in addr;// 客户方地址
} PER_HANDLE_DATA, *PPER_HANDLE_DATA;
typedef struct_PER_IO_DATA//per-I/O数据
{
OVERLAPPEDol;//重叠结构
char buf[BUFFER_SIZE];//数据缓冲区
intnOperationType;// 操作类型
#define OP_READ 1
#define OP_WRITE 2
#define OP_ACCEPT 3
} PER_IO_DATA, *PPER_IO_DATA;
DWORD WINAPI ServerThread(LPVOID lpParam)
{
// 得到完成端口对象句柄
HANDLE hCompletion = (HANDLE)lpParam;
DWORD dwTrans;
PPER_HANDLE_DATA pPerHandle;
PPER_IO_DATA pPerIO;
while(TRUE)
{
//在关联到此完成端口的所有套节字上等待I/O完成
BOOL bOK =::GetQueuedCompletionStatus(hCompletion,
&dwTrans,(LPDWORD)&pPerHandle,(LPOVERLAPPED*)&pPerIO, WSA_INFINITE);
if(!bOK)//在此套节字上有错误发生
{
::closesocket(pPerHandle->s);
::GlobalFree(pPerHandle);
::GlobalFree(pPerIO);
continue;
}
if(dwTrans == 0&&//套节字被对方关闭
(pPerIO->nOperationType== OP_READ || pPerIO->nOperationType ==OP_WRITE))
{
::closesocket(pPerHandle->s);
::GlobalFree(pPerHandle);
::GlobalFree(pPerIO);
continue;
}
switch(pPerIO->nOperationType)//通过per-I/O数据中的nOperationType域查看什么I/O请求完成了
{
caseOP_READ:// 完成一个接收请求
{
pPerIO->buf[dwTrans]= '\0';
printf(pPerIO-> buf);
//继续投递接收I/O请求
WSABUFbuf;
buf.buf= pPerIO->buf ;
buf.len= BUFFER_SIZE;
pPerIO->nOperationType= OP_READ;
DWORDnFlags = 0;
::WSARecv(pPerHandle->s,&buf, 1, &dwTrans,&nFlags,&pPerIO->ol, NULL);
}
break;
case OP_WRITE: //本例中没有投递这些类型的I/O请求
case OP_ACCEPT:
break;
}
}
return 0;
}
void main()
{
int nPort = 4567;
//创建完成端口对象,创建工作线程处理完成端口对象中事件
//参数说明:
//
//HANDLE WINAPI CreateIoCompletionPort(// __in HANDLE FileHandle,要关联的套节字句柄// __in_opt HANDLE ExistingCompletionPort,
//上面创建的完成端口对象句柄// __in ULONG_PTR CompletionKey,
//一个句柄惟一数据,它将与FILEHANDLE套节字句柄关联在一起。
//可在此存储任意类型的信息。// __in DWORD NumberOfConcurrentThreads//);
HANDLE hCompletion =::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
//在此只创建了一个完成端口对象
::CreateThread(NULL, 0, ServerThread,(LPVOID)hCompletion, 0, 0);
// 创建监听套节字,绑定到本地地址,开始监听
SOCKET sListen = ::socket(AF_INET, SOCK_STREAM,0);
SOCKADDR_IN si;
si.sin_family = AF_INET;
si.sin_port = ::ntohs(nPort);
si.sin_addr.S_un.S_addr = INADDR_ANY;
::bind(sListen, (sockaddr*)&si,sizeof(si));
::listen(sListen, 5);
// 循环处理到来的连接
while(TRUE)
{
// 等待接受未决的连接请求
SOCKADDR_IN saRemote;
int nRemoteLen =sizeof(saRemote);
//创建新的接收套节字
SOCKET sNew = ::accept(sListen,(sockaddr*)&saRemote,&nRemoteLen);
//接受到新连接之后,为它创建一个per-handle数据,并将它们关联到完成端口对象。
PPER_HANDLE_DATA pPerHandle=
(PPER_HANDLE_DATA)::GlobalAlloc(GPTR,sizeof(PER_HANDLE_DATA));
pPerHandle->s =sNew;
memcpy(&pPerHandle->addr,&saRemote, nRemoteLen);
//多个套节字对应一个I/O完成对象
::CreateIoCompletionPort((HANDLE)pPerHandle->s,hCompletion, (DWORD)pPerHandle, 0);
// 投递一个接收请求
PPER_IO_DATA pPerIO =(PPER_IO_DATA)::GlobalAlloc(GPTR, sizeof(PER_IO_DATA));
pPerIO->nOperationType= OP_READ;
WSABUF buf;
buf.buf =pPerIO->buf;
buf.len =BUFFER_SIZE;
DWORD dwRecv;
DWORD dwFlags = 0;
::WSARecv(pPerHandle->s,&buf, 1, &dwRecv,&dwFlags,&pPerIO->ol, NULL);
}
}
分享到:
相关推荐
网络程序设计-IOCP与可伸缩网络程序.ppt该文档详细且完整,值得借鉴下载使用,欢迎下载使用,有问题可以第一时间联系作者~
商业编程-源码-IOCP完成端口模型示例代码.zip
高性能并发TCP网络服务-IOCP框架修正VC2008版本 此框架已运用到实际当中,,, 可以真实参考...
libevent-1.4.4-iocp-3
In-IOCP 是一套基于 IOCP(Delphi 版)的开源框架组件,内部作了消息封装,集成用户、消息、文件和数据库管理,支持自定义消息和远程函数,支持 HTTP 基本服务,帮助快速实现网络开发,主要功能: 1、原始数据流...
In-IOCP服务组件库及例子(开源,v1.6.16.960).7z
易语言TCP-IOCP连接源码,TCP-IOCP连接,服务器处理函数,子程序2,标记,向上跳转,调用子程序_,读内存整数,写内存整数,复制内存,取字节集地址,封装分包,CRC32,取类函数地址,取整数型地址,取类指针,启动,停止,取消息类型,...
In-IOCP服务组件库及例子(开源,1.0.4.896_正式版).7z
In-IOCP 是一套基于 IOCP(Delphi 版)的开源框架组件,内部作了消息封装,集成用户、消息、文件和数据库管理,支持自定义消息和远程函数,帮助实现快速网络开发,欢迎大家测试、使用和交流!
In-IOCP服务组件库及例子(1.0.2.887_正式版).7z
TCP-IOCP连接.rar
In-IOCP服务组件库 例子编号 目录 说明 =================================================== 1 UserMgr 客户端/用户管理 2 MsgMgr 消息服务 3 FileMgr 文件服务 4 DbMgr 数据库服务 5 Custom 自定义服务、...
易语言TCP-IOCP模块3.0版源码,TCP-IOCP模块3.0版,取低十六位,消息处理,回调,客户回调1,DialogBoxParam,GetModuleHandle,EndDialog,GetDlgItemText,SetDlgItemText,初始化模块,释放模块,Server_Create,Server_Destroy...
windows 网络编程IOCP的应用。简单的实例。
TCP-IOCP模块3.0版.rar
易语言源码易语言TCP-IOCP连接源码.rar
程序结合易语言特殊功能支持库,调用API函数实现TCP-IOCP的套接字连接。
易语言源码易语言TCP-IOCP模块3.0版源码.rar
一、基于 Accept/AcceptEx 的 In-IOCP 服务组件库。 二、系统说明 基础代码: 1、IOCP服务; 2、消息封装; 3、客户端-服务端传输(MurmurHash64 校验)。 在上述基础上的开发: 1、响应服务; 2、认证...
In-IOCP 是一套基于 IOCP(Delphi 版)的开源框架组件,内部作了消息封装,集成用户、消息、文件和数据库管理,支持自定义消息和远程函数,支持 HTTP 基本服务,帮助快速实现网络开发,欢迎大家测试、使用和交流!