完成端口模型服务端

来源:互联网 发布:淘宝买photoshop 编辑:程序博客网 时间:2024/05/16 15:24

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;}


原创粉丝点击