📄 iocmplt.cpp
字号:
#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 + -