完成端口模型服务端
2011-01-04 21:19
204 查看
windows 完成端口模型服务端
#include<iostream> #include<winsock2.h> #pragma comment(lib,"WS2_32.lib") using namespace std; const int ServerPort=4399; const int MSGSIZE=1024; typedef enum { RECV_POST, SEND_POST }OPERATION_TYPE; typedef struct { WSAOVERLAPPED wsaOverlapped; WSABUF wsaBuffer; char dataBuffer[MSGSIZE]; DWORD recvedDataSize; DWORD flags; OPERATION_TYPE operationType; }COM_IO_OPERATION_DATA,*PIO_OPERATION_DATA; typedef struct _completionKey { SOCKET sock; SOCKADDR_IN sockAddr; }COMPLETION_KEY,*PCOMPLITON_KEY; int LoadSocketLib() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return -1; } if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { WSACleanup( ); return -1; } return 0; } DWORD WINAPI HandleThread(LPVOID completionPortID); BOOL AsyncRecvData(SOCKET clientSOCK); int main() { system("color 2f"); //加载套接字库 if(LoadSocketLib()!=0) { cout<<"Load winsock failed"<<endl; return -1; } //创建完成端口 HANDLE completionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0); if(completionPort==NULL) { cout<<"创建完成端口失败"<<endl; return -1; } SYSTEM_INFO systemInfo; GetSystemInfo(&systemInfo); DWORD dw_ThreadId;//线程ID //创建线程池 for(int i=0;i<systemInfo.dwNumberOfProcessors;i++) { CreateThread(NULL,0,HandleThread,completionPort,0,&dw_ThreadId); } //创建套接字、绑定、设为监听状态 SOCKET serverSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(serverSock==INVALID_SOCKET) { cout<<"create socket failed"<<endl; return -1; } SOCKADDR_IN serverAddr; serverAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY); serverAddr.sin_family=AF_INET; serverAddr.sin_port=htons(ServerPort); if(SOCKET_ERROR==bind(serverSock,(SOCKADDR*)&serverAddr,sizeof(SOCKADDR_IN))) { cout<<"binding failed"<<endl; return -1; } if(SOCKET_ERROR==listen(serverSock,5)) { cout<<"listen failed"<<endl; return -1; } //接受客户端连接请求,并关联到完成端口 SOCKADDR_IN clientAddr; int addrSize=sizeof(SOCKADDR_IN); // PIO_OPERATION_DATA lpper_IO_Data=NULL; cout<<"/t/t/t"<<"...Server begin..."<<endl; PCOMPLITON_KEY pCompletion=NULL; while(1) { SOCKET clientSock=accept(serverSock,(SOCKADDR*)&clientAddr,&addrSize); if(clientSock==INVALID_SOCKET) { closesocket(clientSock); continue; } //pCompletion=(PCOMPLITON_KEY)malloc(sizeof(COMPLETION_KEY)); // pCompletion->sock=clientSock; //pCompletion->sockAddr=clientAddr; cout<<"the client addr is..."<<inet_ntoa(clientAddr.sin_addr)<<"/t"<<ntohs(clientAddr.sin_port)<<endl; if(NULL==CreateIoCompletionPort((HANDLE)clientSock,completionPort,/*(DWORD)pCompletion*/(DWORD)clientSock,0)) { cout<<"套接字关联失败"<<endl; closesocket(clientSock); continue; } AsyncRecvData(clientSock);//发起异步接受操作 } PostQueuedCompletionStatus(completionPort,0xFFFFFFFF,0,NULL); CloseHandle(completionPort); closesocket(serverSock); WSACleanup(); return 0; } BOOL AsyncRecvData(SOCKET clientSock) { PIO_OPERATION_DATA lpper_IO_Data=NULL; lpper_IO_Data=(PIO_OPERATION_DATA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PIO_OPERATION_DATA));//从堆中分配内存块给关联结构体 if(lpper_IO_Data==NULL) { cout<<"allocate failed"<<endl; closesocket(clientSock); //continue; return false; } ZeroMemory(&lpper_IO_Data->wsaOverlapped,sizeof(lpper_IO_Data->wsaOverlapped)); lpper_IO_Data->wsaBuffer.len=MSGSIZE; lpper_IO_Data->wsaBuffer.buf=lpper_IO_Data->dataBuffer; lpper_IO_Data->operationType=RECV_POST; //异步调用,因此当服务器刚开启的时候第一次激发异步接受Recv会失败, if(SOCKET_ERROR==WSARecv(clientSock,&(lpper_IO_Data->wsaBuffer),1,&lpper_IO_Data->recvedDataSize,&lpper_IO_Data->flags,&lpper_IO_Data->wsaOverlapped,NULL)) { if(WSAGetLastError()!=ERROR_IO_PENDING) { cout<<"WSARecv 函数调用失败"<<WSAGetLastError<<endl;//71A23CCE closesocket(clientSock); } } return true; } DWORD WINAPI HandleThread(LPVOID completionPortID) { HANDLE completionPort=(HANDLE)completionPortID; DWORD dwBytesTransferred; SOCKET clientSock; PIO_OPERATION_DATA lp_IO_Data=NULL; //从队列中取出活跃套接字 GetQueuedCompletionStatus(completionPort,&dwBytesTransferred,(unsigned long*)&clientSock,(LPWSAOVERLAPPED*)&lp_IO_Data,INFINITE); if(dwBytesTransferred==0xFFFFFFFF) {//没有活跃套接字 return 0; } if(lp_IO_Data->operationType==RECV_POST) { if(dwBytesTransferred==0) {//客户端关闭 cout<<"客户端关闭"<<endl; closesocket(clientSock); HeapFree(GetProcessHeap(),0,lp_IO_Data); } else {//处理客户端请求 lp_IO_Data->dataBuffer[dwBytesTransferred]='/0'; //send(clientSock,lp_IO_Data->dataBuffer,dwBytesTransferred,0); WSASend(clientSock,&lp_IO_Data->wsaBuffer,1,&lp_IO_Data->recvedDataSize,lp_IO_Data->flags,&lp_IO_Data->wsaOverlapped,NULL); memset(lp_IO_Data,0,sizeof(COM_IO_OPERATION_DATA)); lp_IO_Data->wsaBuffer.buf=lp_IO_Data->dataBuffer; lp_IO_Data->wsaBuffer.len=MSGSIZE; lp_IO_Data->operationType=RECV_POST; WSARecv(clientSock,&lp_IO_Data->wsaBuffer,1,&lp_IO_Data->recvedDataSize,&lp_IO_Data->flags,&lp_IO_Data->wsaOverlapped,NULL); } } return 0; }
相关文章推荐
- Windows下性能最好的I/O模型——完成端口
- 完成端口重叠I/O模型的服务器中,如何存储和管理数万个socket句柄—IOCP代码
- winsock 完成端口 简单服务器模型
- winsock 完成端口 服务器模型(2)
- [置顶] 手把手教你玩转SOCKET模型:完成端口(Completion Port)详解
- 完成端口模型
- IOCP 完成端口 是性能最好的一种I/O模型
- 完成端口模型
- winsock 完成端口 服务器模型(3)
- 完成端口重叠I/O模型的服务器中,存储和管理数万个socket句柄
- Socket模型(二):完成端口(IOCP)
- 完成端口封装(修复Windows 网络与通信程序设计 可伸缩IOCP模型的bug)
- 浅谈Windows网络模型之完成端口模型
- 完成端口模型
- 完成端口I/O模型
- 完成端口模型
- I/O完成端口模型
- 可伸缩的IO完成端口服务器模型(IOCP)
- 完成端口IO模型
- 完成端口模型开发