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

📄 server.cpp

📁 游戏是我在3月5日离职后花3周时间做的。主要目的是验证自己在游戏上相关的编程能力
💻 CPP
字号:
#include "server.h"

Server::~Server()
{

}
Server::Server()
{
	sck_Listen = NULL;
}

BOOL Server::InitServer(HWND hwnd)
{
	hWnd = hwnd;
	memset(m_Zero,0,100);
	if(sck_Listen == NULL)
	{
    	WSADATA		t_wsaData;
     	WSAStartup(MAKEWORD(2,2),&t_wsaData);
    	return TRUE;
	}
	return TRUE;
}

TCHAR* Server::CreateServer()
{
	sockaddr_in	 t_ServerAddress;
	sck_Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,WSA_FLAG_OVERLAPPED);

	//地址初始化
	memset(&t_ServerAddress, 0, sizeof(t_ServerAddress));
    t_ServerAddress.sin_family      = AF_INET;
    t_ServerAddress.sin_addr.s_addr = htonl(INADDR_ANY);
    t_ServerAddress.sin_port        = htons(6666);

	//捆绑ServerSock,(struct sockaddr far *)&dstserver_addr,&len
	bind(sck_Listen,(struct sockaddr *)&t_ServerAddress,sizeof(t_ServerAddress));
	
	//创建IO端口
   	m_hCompletionPort = CreateIoCompletionPort(
		INVALID_HANDLE_VALUE,
		NULL,   // No prior port
		0,      // No key
		0       // Use default  # of threads
        );
	if( m_hCompletionPort == NULL )
	{
		return "error_IO";
	}

	SYSTEM_INFO  t_Sysinfo;  ////cpu
    DWORD        t_dwThreadId;  ////线程ID
    DWORD        t_dwThreads;  ////可用线程个数
	
    GetSystemInfo(&t_Sysinfo);
    t_dwThreads = t_Sysinfo.dwNumberOfProcessors * 2;
    for (DWORD i=0; i<t_dwThreads; i++)
    {
        HANDLE t_hThread;
        t_hThread = CreateThread(
            NULL, 0, Server::THreadFunc, this, 0, &t_dwThreadId
            );
        CloseHandle(t_hThread);
    }

	listen( sck_Listen, 5 );

	DWORD   t_aThreadId;
	HANDLE  t_aThread;
	t_aThread = CreateThread(NULL,0,Server::THreadAccept, this, 0, &t_aThreadId);
	CloseHandle(t_aThread);
////////////////////获取IP
	char szHostName[128];
	if(gethostname(szHostName,128)==0)
	{
		struct hostent *pHost;
		int i;
	pHost=gethostbyname(szHostName);
    for(i=0;pHost!=NULL&&pHost->h_addr_list[i]!=NULL;i++)
	{
    	LPCSTR psz=inet_ntoa(*(struct in_addr*)pHost->h_addr_list[i]);
        sprintf(IP,"%s",psz);
	}
	}
	return IP;
}

DWORD WINAPI Server::THreadFunc(LPVOID lpVoid)
{
	BOOL			t_bResult;
	DWORD			t_dwTranfByte = 0;
	LPOVERLAPPED	t_lpOverlapped;
	KEY*			t_pKey;
	Server *SG_s = (Server*)lpVoid;
	HANDLE			t_hComplete = SG_s->m_hCompletionPort;

	//进入循环,捕获消息
	while(1)
	{
		//获取IO状态,阻塞
		t_bResult = GetQueuedCompletionStatus(
			t_hComplete,
			&t_dwTranfByte,
			(LPDWORD)&t_pKey,
			&t_lpOverlapped,
			INFINITE
            );
		SG_s->AnalyseBuf(t_pKey->s_sRecvBuf.buf);
		Sleep(50);
		SG_s->PostRecv(t_pKey);
	}
	return 0;
}

DWORD WINAPI Server::THreadAccept(LPVOID lpVoid)
{
	SOCKET	t_AccepteSocket;
	KEY*	t_pKey;
	Server *SG_s = (Server*)lpVoid;
		//接受新套接字
    while(1)
	{
        if((t_AccepteSocket = WSAAccept(SG_s->sck_Listen, NULL, NULL, NULL, 0))==SOCKET_ERROR )
		{
			return 0;
		}
		int t_iZero = 0;
		t_pKey = new KEY; ///// new 一个
	
		ZeroMemory(&(t_pKey->s_sRecvOv), sizeof(OVERLAPPED));
		ZeroMemory(&(t_pKey->s_sSendOv), sizeof(OVERLAPPED));
		
		//设置WSASEND后不通知完成端口
		t_pKey->s_sSendOv.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		t_pKey->s_sSendOv.hEvent = (HANDLE)((DWORD)t_pKey->s_sSendOv.hEvent | 0x1);
		t_pKey->s_hSocket = t_AccepteSocket;

		//重叠端口关联
		if( CreateIoCompletionPort(
			(HANDLE)t_AccepteSocket,
			SG_s->m_hCompletionPort,
			(DWORD)t_pKey,   // No key
			0              // Use default # of threads
            )== NULL )
		{
			return 0;
		}	
		//投递RECV操作
		t_pKey->s_sRecvBuf.len	= DATA_BUFSIZE;
		t_pKey->s_sRecvBuf.buf	= t_pKey->s_cRBuffer;
		t_pKey->s_sSendBuf.buf  = t_pKey->s_cSBuffer;
    	SG_s->PostRecv(t_pKey);
     	SendMessage(SG_s->hWnd,SERVER_MSG_GAMEBEGIN,(WPARAM)t_pKey->s_hSocket,NULL);
	}
	return 0;
}

BOOL Server::PostRecv(KEY *a_pKey)
{
	DWORD t_dwRev,t_dwFlag	= 0;
	a_pKey->s_bIsRecv		= true;
	int i					= 0;
	int err;

	//清空缓冲区
	ZeroMemory( a_pKey->s_cRBuffer,DATA_BUFSIZE );
	ZeroMemory(&(a_pKey->s_sRecvOv), sizeof(OVERLAPPED));
	
	//投递接受消息
    while(++i)
	{
		err = WSARecv(a_pKey->s_hSocket,&a_pKey->s_sRecvBuf,1,&t_dwRev,&t_dwFlag,&a_pKey->s_sRecvOv,NULL );

		if( err != SOCKET_ERROR )
		{
			return true;
		}
		err = WSAGetLastError();
		if(  err == ERROR_IO_PENDING )
		{
			return true;
		}
		if( err == ERROR_INVALID_USER_BUFFER ||
			err == ERROR_NOT_ENOUGH_QUOTA ||
			err == ERROR_NOT_ENOUGH_MEMORY )
		{
			if (i == 5)
			{
				Sleep(50);
				continue;
			}
			MessageBox( NULL,"WSARecv错误","PostRecv",NULL );
			return false;
		}
		break;
	}
	return false;
}

BOOL Server::SendBuf(SOCKET sck_c, void *a_pBuf, DWORD a_dwLen)
{

	if( sck_c == NULL ){
		return FALSE;
	}
	send(sck_c,(char*)a_pBuf,a_dwLen,0 );
	return TRUE;
}

void Server::AnalyseBuf(TCHAR *m_cBuffer)
{
	char *head, *tail;
	head = m_cBuffer;
	if(m_Zero[0] != NULL)
	{
		char buf[DATA_BUFSIZE];
		strcpy(buf,m_Zero);
		strcat(buf,m_cBuffer);
		strcpy(m_cBuffer,buf);
		memset(m_Zero,0,100);
	}
	while(1)
	{
    	tail = strstr(head,"|");
    	if(tail == NULL)
		{
		  	if(m_Zero[0] == NULL)
		    	strcpy(m_Zero,head);
		   	else if(m_Zero[0] != NULL)
			   	strcat(m_Zero,head);
			break;
		}
    	char *Command = new char[100];
    	memset(Command,0,100);
		++tail;
    	strncpy(Command,head,tail - head);
		PostMessage(hWnd,SERVER_MSG_RECV,(WPARAM)Command,NULL);
		head = tail;
		if(head == NULL)
			break;
	}

}

⌨️ 快捷键说明

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