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

📄 sockclient.cpp

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

#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"winmm.lib")

CSockClient::CSockClient(void)
{
	m_dwProtocol = SOCK_STREAM;
	m_bRunState = true;
	sprintf( m_strHostIP, "NULL" );
	m_dwHostPort = 0;

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

CSockClient::~CSockClient(void)
{
	m_bRunState = false;
	CloseHandle( m_hEvent[ 0 ] );
	CloseHandle( m_hEvent[ 1 ] );
	Cleanup();
}

bool CSockClient::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 CSockClient::Cleanup(void)
{
	//清除socket
	if( m_sSocket != INVALID_SOCKET )
		closesocket( m_sSocket );
	//清除winsock
	WSACleanup();
}

bool CSockClient::Create(DWORD dwProtocol)
{
	//设置连接协议
	m_dwProtocol = dwProtocol;

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

	//设置套接字运行状态
	m_bRunState = true;
	return true;
}

bool CSockClient::Connect(const char* strIP, DWORD dwPort) 
{
	//创建client线程
	DWORD dwThreadID;
	m_hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)ClientThread, this, 0, &dwThreadID );
	if( m_hThread == NULL )
	{
		DebugMsg("创建client线程错误\n");
		return false;
	}

	if( !strIP )
	{
		DebugMsg( "没有指定目标地址!\n" );
		return false;
	}

	sprintf( m_strHostIP, "%s", strIP );
	m_dwHostPort = dwPort;

	//绑定套接字
	SOCKADDR_IN addr;
	memset( &addr, 0, sizeof(addr) );
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr( m_strHostIP );
	
	if( addr.sin_addr.s_addr == INADDR_NONE )
	{
		LPHOSTENT lphost = gethostbyname( m_strHostIP );
		if( lphost != NULL )
		{
			addr.sin_addr.s_addr = ( ( LPIN_ADDR )lphost->h_addr )->s_addr;
		}
		else
		{
			DebugMsg("无法解析目标地址!\n");
			WSASetLastError(WSAEINVAL);
			return false;
		}
	}

	addr.sin_port = htons( (unsigned short)m_dwHostPort );

	//连接
	if(connect(m_sSocket, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR)
	{
		if(  WSAGetLastError() == WSAEWOULDBLOCK )
		{
			DebugMsg("连接目标失败\n");
			return false;
		}
	}

	//设置事件选择
	if( WSAEventSelect(m_sSocket, m_hEvent[0],FD_CONNECT | FD_CLOSE) == SOCKET_ERROR )
	{
		DebugMsg("连接事件选择错误\n");
		return false;
	}	
	return true;
}

DWORD CSockClient::GetBufferLength(void)
{
	DWORD dwBufferLenght;
	if( ioctlsocket(m_sSocket,FIONREAD,&dwBufferLenght) != SOCKET_ERROR )
		return dwBufferLenght;
	return 0;
}

bool CSockClient::RecvTcp(LPVOID lpBuffer,DWORD dwBufferLenght,DWORD dwFlags ) 
{
	//接收
	if( recv( m_sSocket , (char*)lpBuffer , (int)dwBufferLenght , (int)dwFlags) == SOCKET_ERROR )
	{
		if( WSAGetLastError() != WSAEWOULDBLOCK )
			return false;
	}
	return true;
}

bool CSockClient::SendTcp(LPVOID lpBuffer,DWORD dwBufferLenght,DWORD dwFlags )
{
	//发送
	if( send( m_sSocket , (char*)lpBuffer , (int)dwBufferLenght , (int)dwFlags) == SOCKET_ERROR )
	{
		if( WSAGetLastError() != WSAEWOULDBLOCK )
			return false;
	}
	return true;
}

bool CSockClient::ClientThread(LPVOID lpParam)
{
	CSockClient* pSocket = (CSockClient*)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_CONNECT)
				{
					if( events.iErrorCode[FD_CONNECT_BIT] == 0)
					{
						if( WSAEventSelect(pSocket->GetSocket(),pSocket->GetEvent()[0], FD_WRITE|FD_READ|FD_CLOSE) == SOCKET_ERROR )
						{
							DebugMsg("不能在连接后选择事件\n");
							return false;
						}
					}
					pSocket->GetClientThread()(pSocket,FD_CONNECT,0,(DWORD)events.iErrorCode[FD_CONNECT_BIT]);					
				}
				//当收到消息
				if(events.lNetworkEvents == FD_READ)
				{
					pSocket->GetClientThread()(pSocket,FD_READ,pSocket->GetBufferLength(),(DWORD)events.iErrorCode[FD_READ_BIT]);
				}
				//当发送消息
				if(events.lNetworkEvents == FD_WRITE)
				{
					pSocket->GetClientThread()(pSocket,FD_WRITE,0,(DWORD)events.iErrorCode[FD_WRITE_BIT]);
				}
				//当关闭套接字
				if(events.lNetworkEvents == FD_CLOSE)
				{
					pSocket->SetRunState(false);
					pSocket->GetClientThread()(pSocket,FD_CLOSE,0,(DWORD)events.iErrorCode[FD_CLOSE_BIT]);
				}
			}
			else
			{
				// 检测数据缓冲中是否有数据存在
				if(pSocket->GetBufferLength())
				{
					pSocket->GetClientThread()(pSocket,FD_READ,pSocket->GetBufferLength(),0);
				}
			}
		}
		catch(...)
		{
			static long oldtime = 0;
			long newtime = timeGetTime();
			if( newtime - oldtime >= 10000 )
			{
				oldtime = newtime;
				DebugMsg("网络连接超时,网速也太慢了\n");
			}
		}
	}
	return true;
}

⌨️ 快捷键说明

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