AcceptEx函数与完成端口的结合使用例子
来源:互联网 发布:淘宝店教程 编辑:程序博客网 时间:2024/05/22 06:15
这是在学《Windows网络编程(第二版)》第六章时制作的一个例子由于书中没有给出简洁的例子,本人在学这里时就费了很多时间。现在把完成的代码贴出来,供大家参考。下面包括了主程序部分,工作线程在(2)中贴出,由于代码太长。本程序在VS2003编译器编译运行。在6.0下可能需要稍加修改。#include <iostream>#include <winsock2.h>#include <ws2tcpip.h>#include <mswsock.h> //微软扩展的类库using namespace std;#define SEND 0#define RECV 1#define ACCEPT 2#define DATA_LENGTH 1000//单句柄数据定义typedef struct _PER_HANDLE_DATA{ SOCKET socket; //相关的套接字 SOCKADDR_STORAGE clientAddr; //客户端的地址}PER_HANDLE_DATA,*LPPER_HANDLE_DATA;//但IO操作数据typedef struct{ OVERLAPPED overlapped; WSABUF buffer; //一个数据缓冲区,用于WSASend/WSARecv中的第二个参数 char dataBuffer[DATA_LENGTH]; //实际的数据缓冲区 int dataLength; //实际的数据缓冲区长度 int operatorType; //操作类型,可以为SEND/RECV两种 SOCKET client; //分别表示发送的字节数和接收的字节数}PER_IO_DATA,*LPPER_IO_DATA;void main(){ HANDLE CompletionPort; WSADATA data; SYSTEM_INFO info; SOCKADDR_IN addr; SOCKET Listen; unsigned int i; WSAStartup(MAKEWORD(2,2),&data); //创建一个IO完成端口 CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0); //确定处理器的数量 GetSystemInfo(&info); //创建线城 for(i=0;i<info.dwNumberOfProcessors * 2;i++) { //根据处理器的数量创建相应多的处理线程 HANDLE thread = CreateThread(NULL,0,ServerThread,CompletionPort,0,NULL); CloseHandle(thread); } //创建一个监听套接字(进行重叠操作) Listen = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED); //将监听套接字与完成端口绑定 LPPER_HANDLE_DATA perDandleData; perDandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR,sizeof(PER_HANDLE_DATA)); perDandleData->socket = Listen; CreateIoCompletionPort((HANDLE)Listen,CompletionPort,(ULONG_PTR)perDandleData,0); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(5500); bind(Listen,(PSOCKADDR)&addr,sizeof(addr)); listen(Listen,5); LPFN_ACCEPTEX lpfnAcceptEx = NULL; //AcceptEx函数指针 //Accept function GUID GUID guidAcceptEx = WSAID_ACCEPTEX; //get acceptex function pointer DWORD dwBytes = 0; if(WSAIoctl(Listen,SIO_GET_EXTENSION_FUNCTION_POINTER, &guidAcceptEx,sizeof(guidAcceptEx),&lpfnAcceptEx,sizeof(lpfnAcceptEx), &dwBytes,NULL,NULL)==0) cout<<"WSAIoctl success..."<<endl; else{ cout<<"WSAIoctl failed..."<<endl; switch(WSAGetLastError()) { case WSAENETDOWN: cout<<""<<endl; break; case WSAEFAULT: cout<<"WSAEFAULT"<<endl; break; case WSAEINVAL: cout<<"WSAEINVAL"<<endl; break; case WSAEINPROGRESS: cout<<"WSAEINPROGRESS"<<endl; break; case WSAENOTSOCK: cout<<"WSAENOTSOCK"<<endl; break; case WSAEOPNOTSUPP: cout<<"WSAEOPNOTSUPP"<<endl; break; case WSA_IO_PENDING: cout<<"WSA_IO_PENDING"<<endl; break; case WSAEWOULDBLOCK: cout<<"WSAEWOULDBLOCK"<<endl; break; case WSAENOPROTOOPT: cout<<"WSAENOPROTOOPT"<<endl; break; } return; } //while(true) //{ //准备调用 AcceptEx 函数,该函数使用重叠结构并于完成端口连接 LPPER_IO_DATA perIoData = (LPPER_IO_DATA)GlobalAlloc(GPTR,sizeof(PER_IO_DATA)); memset(&(perIoData->overlapped),0,sizeof(OVERLAPPED)); perIoData->operatorType = ACCEPT; //在使用AcceptEx前需要事先重建一个套接字用于其第二个参数。这样目的是节省时间 //通常可以创建一个套接字库 perIoData->client = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,0,0,WSA_FLAG_OVERLAPPED); perIoData->dataLength = DATA_LENGTH; DWORD flags = 0; //调用AcceptEx函数,地址长度需要在原有的上面加上16个字节 //注意这里使用了重叠模型,该函数的完成将在与完成端口关联的工作线程中处理 cout<<"Process AcceptEx function wait for client connect..."<<endl; int rc = lpfnAcceptEx(Listen,perIoData->client,perIoData->dataBuffer, perIoData->dataLength-((sizeof(SOCKADDR_IN)+16)*2), sizeof(SOCKADDR_IN)+16,sizeof(SOCKADDR_IN)+16,&dwBytes, &(perIoData->overlapped)); if(rc == FALSE) { if(WSAGetLastError()!=ERROR_IO_PENDING) cout<<"lpfnAcceptEx failed.."<<endl; } cin>>i; closesocket(Listen); WSACleanup();}
0 0
- AcceptEx函数与完成端口的结合使用例子
- AcceptEx函数与完成端口的结合使用例子
- 完成端口与AcceptEx
- 使用AcceptEx方法的完成端口
- 关于完成端口IOCP异步接收连接函数AcceptEx注意事项
- 完成端口IOCP与AcceptEx, NO MFC, JUST win api
- 函数对象 与 count_if()结合使用 例子
- windows完成端口 等待客户端发送一次消息才能完成AcceptEx操作的解决方法
- 完成端口的一个例子
- 完成端口的一个例子
- 完成端口的一个例子
- 完成端口的一个例子
- 完成端口的一个例子
- IOCP配合AcceptEx的例子
- IOCP配合AcceptEx的例子
- IOCP配合AcceptEx的例子
- 使用WSAIoctl获取socket扩展函数(如AcceptEx)的指针
- AcceptEx函数的示例代码
- 使用commons-daemon把jar文件做成服务
- 从毕业生成为职业人(转载)
- AndroidAnnotations——Handling options menu处理选项菜单
- RFC search
- 究竟是什么阻碍了物联网的普及?
- AcceptEx函数与完成端口的结合使用例子
- 运维常用状态返回码
- linux网络编程之socket(六):利用recv和readn函数实现readline函数
- js数组操作
- shrio 权限管理filterChainDefinitions过滤器配置
- ethernet switch loopback test transfer
- 13.56M读卡器开发详解二(RC522驱动程序)
- 在eclipse上执行Nutch报错com.google.common.util.concurrent.ThreadFactoryBuilder
- 几种常见浏览器内核简介