⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iocmplt.cpp

📁 由本人编写的一个完成端口测试程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include "DataStruct.h"


#pragma comment(lib, "Ws2_32")
HANDLE  hMutex;
char log[50];
void AddLog(const char *strInfo,DWORD size);
void main(void)
{
	
   SOCKADDR_IN InternetAddr,RemoteAddr;
   SOCKET Listen;
   SOCKET Accept;
   HANDLE CompletionPort;
   SYSTEM_INFO SystemInfo;
   unsigned int i;
   DWORD RecvBytes;
   DWORD Flags;
   DWORD ThreadID;
   WSADATA wsaData;
   DWORD Ret;
   hMutex = CreateMutex (NULL,FALSE,TEXT("LOGObject"));
   if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)//初始化sock
   {
      printf("WSAStartup failed with error %d\n", Ret);
      return;
   }

   // Setup an I/O completion port.

   if ((CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)
   {
      printf( "CreateIoCompletionPort failed with error: %d\n", GetLastError());
      return;
   }

   // Determine how many processors are on the system.

   GetSystemInfo(&SystemInfo);

   // Create worker threads based on the number of processors available on the
   // system. Create two worker threads for each processor.

   for(i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)//建立工作者线程
   {
      HANDLE ThreadHandle;

      // Create a server worker thread and pass the completion port to the thread.

      if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, CompletionPort,
         0, &ThreadID)) == NULL)
      {
         printf("CreateThread() failed with error %d\n", GetLastError());
         return;
      }

      // Close the thread handle
      CloseHandle(ThreadHandle);
   }

   // Create a listening socket

   if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
      WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)//建立监听sock
   {
      printf("WSASocket() failed with error %d\n", WSAGetLastError());
      return;
   } 
   printf("create socket ok\n");
   strcpy(log,"");
   sprintf(log,"create socket ok\r\n");
   AddLog(log,strlen(log));
   InternetAddr.sin_family = AF_INET;
   InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
   InternetAddr.sin_port = htons(PORT);

   if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)//绑定
   {
      printf("bind() failed with error %d\n", WSAGetLastError());
      return;
   }
   printf("bind port %d ok\n",PORT);
   sprintf(log,"bind port %d ok\r\n",PORT);
   AddLog(log,strlen(log));
   // Prepare socket for listening

   if (listen(Listen, 200) == SOCKET_ERROR)//监听
   {
      printf("listen() failed with error %d\n", WSAGetLastError());
      return;
   }
   printf("listen ok\n");
   sprintf(log,"listen ok\r\n");
   AddLog(log,strlen(log));
   // Accept connections and assign to the completion port.
   int j=sizeof(RemoteAddr);
   while(TRUE)
   {
      if ((Accept = WSAAccept(Listen, (PSOCKADDR) &RemoteAddr,&j, NULL, 0)) == SOCKET_ERROR)//接收连接
      {
         printf("WSAAccept() failed with error %d\n", WSAGetLastError());
         return;
      }
      LPPER_HANDLE_DATA lp_key = m_key_group.GetBlank();

      // Associate the accepted socket with the original completion port.
      
	  printf("%s connected\n", inet_ntoa(RemoteAddr.sin_addr));//显示对端地址
	  strcpy(log,"");
      sprintf(log,"%s connected\r\n", inet_ntoa(RemoteAddr.sin_addr));
      AddLog(log,strlen(log));
      lp_key->Socket = Accept;

      if (CreateIoCompletionPort((HANDLE) Accept, CompletionPort, (DWORD) lp_key,
         0) == NULL)//将新sock绑定到完成端口
      {
         printf("CreateIoCompletionPort failed with error %d\n", GetLastError());
         return;
      }

      // Create per I/O socket information structure to associate with the 
      // WSARecv call below.
       LPPER_IO_OPERATION_DATA lp_io = m_io_group.GetBlank();
	 
      //为单IO数据结构赋初值
      ZeroMemory(&(lp_io->Overlapped), sizeof(OVERLAPPED));
	  lp_io->gameinfo.Room=0;
	  lp_io->gameinfo.Desk=0;     	  
	  lp_io->gameinfo.Sock=Accept;
      //lp_io->BytesSEND = 0;
      //lp_io->BytesRECV = 0;
      lp_io->DataBuf.len = sizeof(GameMsg);
      lp_io->DataBuf.buf = lp_io->Buffer;
	  lp_io->type=IOCP_RECV;

      Flags = 0;//一个in/out参数
      if (WSARecv(Accept, &(lp_io->DataBuf), 1, &RecvBytes, &Flags,
         &(lp_io->Overlapped), NULL) == SOCKET_ERROR)//接收一次
      {
         if (WSAGetLastError() != ERROR_IO_PENDING)
         {
            printf("WSARecv() failed with error %d\n", WSAGetLastError());
            return;
         }
      }
   }
}
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)//工作者线程
{
   HANDLE CompletionPort = (HANDLE) CompletionPortID;
   DWORD BytesTransferred;
   LPPER_HANDLE_DATA PerHandleData;
   LPPER_IO_OPERATION_DATA PerIoData;
   DWORD RecvBytes;
   DWORD Flags;
   
 while(TRUE)
 {    if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
         (LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)
      {
         printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
         return 0;
      }        
		 ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
         PerIoData->DataBuf.buf = PerIoData->Buffer ;
         PerIoData->DataBuf.len = BytesTransferred ;
switch(PerIoData->type)
{
 case IOCP_RECV://是接收消息
	{
	 GameMsg package;
	 memcpy(&(char&)package,&PerIoData->Buffer,BytesTransferred);//得到所发的信息
	switch(package.MsgType)
	 {
	  case GAME_STATE_LOGIN://登陆消息
		 {
		  LoginInfo login;
		  ZeroMemory(&login, sizeof(LoginInfo));
		  memcpy(&login,&package.Buffer,package.Size);
		  PerIoData->gameinfo.Room=login.Room;
          PerIoData->gameinfo.Desk=login.Desk;
	      strcpy(PerIoData->gameinfo.Name,login.Name);
		  printf("player login room:%d desk:%d name:%s\n", login.Desk ,PerIoData->gameinfo.Room,PerIoData->gameinfo.Name);
		  sprintf(log,"player login room:%d desk:%d name:%s\r\n", login.Desk ,PerIoData->gameinfo.Room,PerIoData->gameinfo.Name);
          AddLog(log,strlen(log));
		  PerIoData->type=IOCP_SEND;
          SendToClient(PerHandleData->Socket,&(char&)login,sizeof(LoginInfo),SERVER_SUCCESS,PerIoData);
		 }
		 break;
	  case GAME_STATE_CREATE://创建游戏消息
		 {
		  CreateInfo createinfo;
	      ZeroMemory(&createinfo, sizeof(CreateInfo));
		  memcpy(&createinfo,&package.Buffer,package.Size);	
		  LPGameInfo gameInfo = gameInfo_group.GetBlank();//分配空间,保存游戏信息
		  gameInfo->Room=PerIoData->gameinfo.Room;
          gameInfo->Desk=PerIoData->gameinfo.Desk;
	      strcpy(gameInfo->HostName,PerIoData->gameinfo.Name);
		  gameInfo->hHost=PerHandleData->Socket;
		  gameInfo->hClient=0;
		  gameInfo->ClientCount=0;
	 	  gameInfo->HostCount=0;
		  strcpy(gameInfo->GameName,createinfo.GameName);
		  printf("player:%s create game:%s\n",gameInfo->HostName,gameInfo->GameName);
          sprintf(log,"player:%s create game:%s\r\n",gameInfo->HostName,gameInfo->GameName);
          AddLog(log,strlen(log));
          SendToClient(PerHandleData->Socket,&(char&)createinfo,sizeof(CreateInfo),SERVER_SUCCESS,PerIoData);
		 }
		 break;
	  case GAME_STATE_JOIN://加入游戏信息
		 {
		  JoinInfo joininfo;
		  ZeroMemory(&joininfo, sizeof(JoinInfo));
		  memcpy(&joininfo,&package.Buffer,package.Size);
		  //查找是否已存在此游戏
		  LPGameInfo gameInfo =NULL;
		  GameInfo_POS pos;
		  gameInfo_group.GetHeadPosition( pos );
		  if(pos==NULL)
		  {printf("join error have no such game!\n");
		   sprintf(log,"join error have no such game!\r\n");
          AddLog(log,strlen(log));
		  SendToClient(PerHandleData->Socket,&(char&)joininfo,sizeof(JoinInfo),SERVER_FAIL,PerIoData);}
		  else
		  {
		  while( pos != NULL )
		  {
		  gameInfo = gameInfo_group.GetNext( pos );
		  if(PerIoData->gameinfo.Room==gameInfo->Room&&PerIoData->gameinfo.Desk==gameInfo->Desk
			&&gameInfo->hClient==0&&(strcmp(gameInfo->GameName,joininfo.GameName)==0))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -