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

📄 sockserver.cpp

📁 冰人引擎,本2d游戏引擎定位于游戏次中层引擎。他不像CDX等引擎那样
💻 CPP
字号:
#include "stdafx.h"
#include "sockServer.h"

CSockServer::CSockServer(void)
{
	sprintf( m_strIP, "NULL" );
	m_dwPort = 0;
	m_dwProtocol = SOCK_STREAM;

	m_hEvent[0] = CreateEvent(NULL,0,0,0);
	m_hEvent[1] = CreateEvent(NULL,0,0,0);

}

CSockServer::~CSockServer(void)
{
	m_bRunState = false;

	CloseHandle( m_hEvent[0] );
	CloseHandle( m_hEvent[1] );

	Cleanup();
}

bool CSockServer::Initialize(void)
{
	WSADATA wsaData;
	//建立winsock
	if( WSAStartup( 0x0202 , &wsaData ) )
	{
		DebugMsg( "WSAStartup失败!\n" );
		return false;
	}
	//判断版本
	if( wsaData.wVersion != 0x0202 )
	{
		DebugMsg( "系统不支持Winsock 2.0!\n" );
		WSACleanup();
		return false;
	}
	return true;
}

void CSockServer::Cleanup(void)
{
	//清除socket
	if( m_sSocket != INVALID_SOCKET )
		closesocket( m_sSocket );
	//清除winsock
	WSACleanup();
}

bool CSockServer::Create(const char* strIP, DWORD dwPort,DWORD dwProtocol)
{
	sprintf( m_strIP, "%s", strIP );
	m_dwPort = dwPort;
	m_dwProtocol = dwProtocol;

	m_sSocket = socket(PF_INET, m_dwProtocol, 0);
	if(m_sSocket == INVALID_SOCKET)
	{
		DebugMsg("创建socket错误\n");
		return false;
	}

	SOCKADDR_IN sockAddr;
	memset( &sockAddr , 0 , sizeof( sockAddr ) );
	sockAddr.sin_family = AF_INET;
	if( m_strIP )
	{
		sockAddr.sin_addr.s_addr = inet_addr( m_strIP );
		if( sockAddr.sin_addr.s_addr == INADDR_NONE )
		{
			WSASetLastError( WSAEINVAL );
			DebugMsg("无法解析IP!\n");
			return false;
		}
	}
	else
	{
		sockAddr.sin_addr.s_addr = htonl( INADDR_ANY );
	}
	sockAddr.sin_port = htons( ( WORD )m_dwPort );

	if( bind( m_sSocket , ( SOCKADDR * )&sockAddr , sizeof( sockAddr ) ) == SOCKET_ERROR )
	{
		DebugMsg("绑定错误\n");
		return false;
	}

	return true;
}

bool CSockServer::Listen(DWORD dwMaxNumber)
{
	
	//侦听
	if( listen(m_sSocket,(int)dwMaxNumber) == SOCKET_ERROR )
	{
		DebugMsg("侦听失败了\n");
		return false;
	}
	//设置事件选择
	if( WSAEventSelect(m_sSocket,m_hEvent[0],FD_ACCEPT|FD_CLOSE) == SOCKET_ERROR )
	{
		DebugMsg("侦听事件选择失败\n");
		return false;
	}

	//创建侦听线程
	DWORD dwThreadID;
	m_hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ListenThread,this,0,&dwThreadID);
	if( m_hThread == NULL )
	{
		DebugMsg("创建侦听线程错误\n");
		return false;
	}
	//创建服务端响应消息线程
	m_hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ServerThread,this,0,&dwThreadID);
	if( m_hThread == NULL )
	{
		DebugMsg("创建服务端响应消息线程错误\n");
		return false;
	}

	return true;
}

bool CSockServer::Accept(void)
{
	if(m_sSocket == INVALID_SOCKET)
	{
		DebugMsg("accept中socket失败!\n");
		return false;
	}

	//生成一个新的客户端对象
	CSockClient*	pSocket = new CSockClient;
	SOCKADDR_IN		sockAddr;
	int iLen		= sizeof(sockAddr);

	memset(&sockAddr,0,sizeof(sockAddr));
	sockAddr.sin_family			= AF_INET;
	
	pSocket->SetSocket(accept(m_sSocket,(sockaddr*)&sockAddr,&iLen));
	if(pSocket->GetSocket() == INVALID_SOCKET)
	{
		DebugMsg("accept连接失败!\n");
		SAFE_DELETE(pSocket);
		return false;
	}

	if(WSAEventSelect(pSocket->GetSocket(),pSocket->GetEvent()[0],FD_READ|FD_WRITE|FD_CLOSE) == SOCKET_ERROR )
	{
		DebugMsg("accept事件选择连接失败!\n");
		SAFE_DELETE(pSocket);
		return false;
	}

	pSocket->SetClientThread(m_pServerThreadMessage);
	//添加到客户端列表
	InstrSocket(pSocket);

	pSocket->SetIP(inet_ntoa(sockAddr.sin_addr));
	pSocket->SetPort((DWORD)ntohs(sockAddr.sin_port));
	
	return true;
}

bool CSockServer::SendTcpAll(LPVOID lpBuffer,DWORD dwBufferLenght,DWORD dwFlags )
{
	CheckList();
	list < CSockClient* >::iterator		Pointer;
	for( Pointer = m_ClientList.begin(); Pointer != m_ClientList.end(); Pointer ++ )
	{
		CSockClient* Socket = * Pointer;
		if( send( Socket->GetSocket() , (char*)lpBuffer , (int)dwBufferLenght , (int)dwFlags) == SOCKET_ERROR )
		{
			if( WSAGetLastError() != WSAEWOULDBLOCK )
			return false;
		}
	}
	return true;
}

bool CSockServer::CheckList(void)
{
	list < CSockClient* >::iterator		Pointer;
	for( Pointer = m_ClientList.begin(); Pointer != m_ClientList.end(); Pointer ++ )
	{
		CSockClient* Socket = * Pointer;
		if( !Socket->GetRunState() )
		{
			DeleteSocket(Socket);
			SAFE_DELETE(Socket);
			return true;
		}
	}
	return true;
}

bool CSockServer::ListenThread(LPVOID lpParam)
{
	CSockServer* pSocket = (CSockServer*)lpParam;
	if( pSocket == NULL )
		return false;
	//进入事件枚举循环
	while(1)
	{
		if(!pSocket->GetRunState())
		{
			DebugMsg("线程终于结束了\n");
            return false;
		}
		//等等那些事件的设定了
		if( WaitForMultipleObjects( 2 , pSocket->GetEvent() , false , 10 ) == 1 )
		{
			DebugMsg("服务端侦听线程事件没响应\n");
			return false;
		}

		WSANETWORKEVENTS events;
		//开try
		try
		{
			// 枚举网络事件
			if(WSAEnumNetworkEvents(pSocket->GetSocket(),pSocket->GetEvent()[0],&events))
			{
				DebugMsg("服务端侦听线程枚举网络事件错误\n");
				return false;
			}
			if(events.lNetworkEvents != 0)
			{
				//当连接成功
				if(events.lNetworkEvents == FD_ACCEPT)
				{
					pSocket->GetListenThread()(pSocket,FD_ACCEPT,0,(DWORD)events.iErrorCode[FD_ACCEPT_BIT]);
				}
				//当关闭套接字
				if(events.lNetworkEvents == FD_CLOSE)
				{
					pSocket->GetListenThread()(pSocket,FD_CLOSE,0,(DWORD)events.iErrorCode[FD_CLOSE_BIT]);
				}
			}
		}
		catch(...)
		{
			static long oldtime = 0;
			long newtime = timeGetTime();
			if( newtime - oldtime >= 10000 )
			{
				oldtime = newtime;
				DebugMsg("网络侦听超时,说不定是掉了\n");
			}
		}
	}
	return true;
}

bool CSockServer::ServerThread(LPVOID lpParam)
{
	list <CSockClient*>::iterator		Pointer;

	CSockServer* pSocket = (CSockServer*)lpParam;
	if(pSocket == NULL)
		return false;

	while(1)
	{
		pSocket->CheckList();
		//历遍客户端
		for( Pointer = pSocket->GetClientList()->begin(); Pointer != pSocket->GetClientList()->end(); Pointer ++ )
		{
			CSockClient* Socket = *Pointer;
			if(!pSocket->GetRunState())
				return false;
						
			WSANETWORKEVENTS events;
			try
			{
				// 枚举网络事件
				if( WSAEnumNetworkEvents(Socket->GetSocket(),Socket->GetEvent()[0],&events))
				{
					DebugMsg("服务端消息线程枚举网络事件错误\n");
				}
				if( events.lNetworkEvents != 0 )
				{
					// 收到消息
					if( events.lNetworkEvents == FD_READ )
					{
						Socket->GetClientThread()(Socket,FD_READ,Socket->GetBufferLength(),(DWORD)events.iErrorCode[FD_READ_BIT]);
					}
					if( events.lNetworkEvents == FD_WRITE )
					{
						Socket->GetClientThread()(Socket,FD_WRITE,0,(DWORD)events.iErrorCode[FD_WRITE_BIT]);
					}
					// 关闭套接字
					if( events.lNetworkEvents == FD_CLOSE )
					{
						//Socket->SetRunState(false);
						Socket->GetClientThread()(Socket,FD_CLOSE,0,(DWORD)events.iErrorCode[FD_CLOSE_BIT]);
					}
				}
				else
				{
					// 检测数据缓冲中是否有数据存在
					if(Socket->GetBufferLength())
					{
						Socket->GetClientThread()(Socket,FD_READ,Socket->GetBufferLength(),0);
					}
				}
			}
			catch(...)
			{
				static long old = 0;
				long now = timeGetTime();
				if( now - old >= 10000 )
				{
					old = now;
					DebugMsg("服务器响应消息线程发生超时,说不定是掉了\n!");
				}
			}
		}
		Sleep(1);
	}
	return true;
}

⌨️ 快捷键说明

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