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

📄 socket.h

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 H
📖 第 1 页 / 共 2 页
字号:
#ifdef	LOGFILE
			LogSave("Message: outbuf len average is %d.", pf_nOutbufAverage / PF_OUTBUFCOUNT);
			LogSave("Message: outbuf len max is %d.", pf_nOutbufMax);
#endif
			pf_nOutbufAverage	= 0;
			pf_nOutbufMax		= 0;
			pf_nOutbufCount		= 0;
		}
		else
		{
			pf_nOutbufAverage = pf_nOutbufAverage + m_nOutbufLen;
			if(pf_nOutbufMax < m_nOutbufLen)
				pf_nOutbufMax = m_nOutbufLen;
			pf_nOutbufCount++;
		}
#endif

		return true;

	}catch(...){ 
#ifdef	LOGFILE
		LogSave("CATCH ERROR: SendMsg()."); 
#endif
		exit(5); 
	}
}

template <unsigned char a1, unsigned char b1, unsigned char c1, unsigned char fst1, 
			unsigned char a2, unsigned char b2, unsigned char c2, unsigned char fst2>
BOOL CGameSocket<a1, b1, c1, fst1, a2, b2, c2, fst2>::ReceiveMsg(void* pBuf, int& nSize)
{
	try
	{
		if(pBuf == NULL)
		{
#ifdef	LOGFILE
			LogSave("ERROR: ReceiveMsg()参数错误.");
#endif
			exit(5);
		}

		//检查参数
		if(nSize <= 0 || nSize >_MAX_MSGSIZE)
		{
#ifdef	ALPHA_X
#ifdef	LOGFILE
			LogSave("警告: ClientSocketReceiveMsg(void* pBuf, int& nSize[%d])参数错误, 忽略", nSize);
#endif
#endif
		}
		try
		{
			char temp = *((char *)pBuf);
		}
		catch(...)
		{
#ifdef	LOGFILE
			LogSave("CATCH ERROR: ReceiveMsg() parameter [pBuf] is invalid point.");
#endif
			exit(5);
		}

//失效也可取数据		if(!m_bState)	return false;

		// 检查是否有一个消息
		if(m_nInbufLen < 2)
		{
			if(!RecvFromSock() || m_nInbufLen < 2)		// 这个m_nInbufLen更新了
				return false;
		}

		int packsize = (u_char)m_bufInput[m_nInbufStart] + 
					(u_char)m_bufInput[(m_nInbufStart + 1) % INBUFSIZE] * 256;	//? 因为有回卷,必须分开算

		if(packsize <= 0 || packsize > _MAX_MSGSIZE)			//? 检测消息包尺寸错误
		{
#ifdef	LOGFILE
			LogSave("ERROR:接收到一个消息包尺寸超长[%d]的消息!!!", packsize);
#endif
			m_nInbufLen = 0;		// 直接清空INBUF
			m_nInbufStart = 0;
			Destroy();
			exit(5);
		}

		// 检查消息是否完整
		if(packsize > m_nInbufLen)
		{
			if(!RecvFromSock() || packsize > m_nInbufLen)	//? 这个m_nInbufLen已更新
				return false;
		}

		// 复制出一个消息
		if(m_nInbufStart + packsize > INBUFSIZE)		// 数据回卷
		{
			int copylen = INBUFSIZE - m_nInbufStart;
			assert(copylen < packsize);
			assert(m_nInbufStart + copylen == INBUFSIZE);
			try{
				memcpy(pBuf, m_bufInput + m_nInbufStart, copylen);
			}catch(...){
#ifdef	LOGFILE
				LogSave("CATCH ERROR:memcpy(pBuf, m_bufInput + m_nInbufStart[%d], copylen[%d]);", m_nInbufStart, copylen);
#endif
				exit(5);
			}
			//assert(copylen < packsize);
			assert(packsize - copylen < INBUFSIZE);
			try{
				memcpy((unsigned char *)pBuf + copylen, m_bufInput, packsize - copylen);
			}catch(...){
#ifdef	LOGFILE
				LogSave("CATCH ERROR:memcpy(pBuf + copylen[%d], m_bufInput, packsize[%d] - copylen);", copylen, packsize);
#endif
				exit(5);
			}
			nSize = packsize;
		}
		else
		{
			assert(m_nInbufStart + packsize <= INBUFSIZE);
			try{
				memcpy(pBuf, m_bufInput + m_nInbufStart, packsize);
			}catch(...){
#ifdef	LOGFILE
				LogSave("CATCH ERROR:memcpy(pBuf, m_bufInput + m_nInbufStart[%d], packsize[%d]);", m_nInbufStart, packsize);
#endif
				exit(5);
			}
			nSize = packsize;
		}
/*
		if(nSize != 9 || memcmp(pBuf, "\x09\x00\x99\x99\x00\x01\x02\x03\x04", 9) != 0)
		{
#ifdef	LOGFILE
			LogSave("TEMP: 消息长度[%d]", nSize);
#endif
			char buf[10];
			sprintf(buf, "%02X %02X %02X %02X %02X %02X %02X %02X %02X", 
							((char*)pBuf)[0],
							((char*)pBuf)[1],
							((char*)pBuf)[2],
							((char*)pBuf)[3],
							((char*)pBuf)[4],
							((char*)pBuf)[5],
							((char*)pBuf)[6],
							((char*)pBuf)[7],
							((char*)pBuf)[8] );
#ifdef	LOGFILE
			LogSave("TEMP: 消息内容[%s]", buf);
			LogSave("TEMP:START[%d]", m_nInbufStart);
			LogSave("TEMP: LEN[%d]", m_nInbufLen);
#endif
		}
*/

		// 从BUF中删除该消息
		//if(m_nInbufLen - packsize > 0)
		//	memcpy(m_bufInput, m_bufInput + packsize, m_nInbufLen - packsize);
		m_nInbufStart = (m_nInbufStart + packsize) % INBUFSIZE;
		m_nInbufLen -= packsize;
		assert(m_nInbufStart >= 0 && m_nInbufStart < INBUFSIZE);
		assert(m_nInbufLen >= 0);
		return	true;

	}catch(...){ 
#ifdef	LOGFILE
		LogSave("CATCH ERROR: ReceiveMsg()."); 
#endif
		exit(5); 
	}
}

template <unsigned char a1, unsigned char b1, unsigned char c1, unsigned char fst1, 
			unsigned char a2, unsigned char b2, unsigned char c2, unsigned char fst2>
BOOL CGameSocket<a1, b1, c1, fst1, a2, b2, c2, fst2>::RecvFromSock(void)		// 从网络中读取尽可能多的数据
{
//内部函数	try{
	// 接收一段数据
	if(m_bState && m_nInbufLen < INBUFSIZE)
	{
		// 接收第一段数据
		int	savelen, savepos;			// 数据要保存的长度和位置
		if(m_nInbufStart + m_nInbufLen < INBUFSIZE)		// INBUF中的剩余空间有回绕
			savelen = INBUFSIZE - (m_nInbufStart + m_nInbufLen);		// 后部空间长度
		else
			savelen = INBUFSIZE - m_nInbufLen;
		savepos = (m_nInbufStart + m_nInbufLen) % INBUFSIZE;
		assert(savepos + savelen <= INBUFSIZE);
		int inlen = recv(m_sockClient, m_bufInput + savepos, savelen, 0);
		if(inlen > 0)
		{
//			LogSave("接收到 %d 个字节.", inlen);			//???
#ifdef	ENCRYPT
			// 消息解密
			if(a1 || b1 || c1 || fst1 || a2 || b2 || c2 || fst2)
				m_cRecvEncrypt.Encrypt((unsigned char *)m_bufInput + savepos, inlen);
#endif
			m_nInbufLen += inlen;
			assert(m_nInbufLen <= INBUFSIZE);

			// 接收第二段数据
			if(inlen == savelen && m_nInbufLen < INBUFSIZE)
			{
				int savelen = INBUFSIZE - m_nInbufLen;
				int savepos = (m_nInbufStart + m_nInbufLen) % INBUFSIZE;
				assert(savepos + savelen <= INBUFSIZE);
				int inlen = recv(m_sockClient, m_bufInput + savepos, savelen, 0);
				if(inlen > 0)
				{
#ifdef	ENCRYPT
					// 消息解密
					if(a1 || b1 || c1 || fst1 || a2 || b2 || c2 || fst2)
						m_cRecvEncrypt.Encrypt((unsigned char *)m_bufInput + savepos, inlen);
#endif	
					m_nInbufLen += inlen;
					assert(m_nInbufLen <= INBUFSIZE);
				}
				else if(inlen == 0)
				{
#ifdef	LOGFILE
					LogSave("ERROR: 服务器已经关闭!");
#endif
					Destroy();
					return false;
				}
				else
				{
					// 连接已断开或者错误(包括阻塞)
					int err = WSAGetLastError();
					if(err != WSAEWOULDBLOCK)
					{
#ifdef	LOGFILE
						LogSave("ERROR %d: recv failed.", err);
#endif
						Destroy();
						return false;
					}
				}
			}	// 第二段

/*#ifdef	_DEBUG_X
			if(pf_nInbufCount >= PF_INBUFCOUNT)
			{
				LogSave("Message: inbuf len average is %d.", pf_nInbufAverage / PF_INBUFCOUNT);
				LogSave("Message: inbuf len max is %d.", pf_nInbufMax);
				pf_nInbufAverage	= 0;
				pf_nInbufMax		= 0;
				pf_nInbufCount		= 0;
			}
			else
			{
				pf_nInbufAverage = pf_nInbufAverage + m_nInbufLen;
				if(pf_nInbufMax < m_nInbufLen)
					pf_nInbufMax = m_nInbufLen;
				pf_nInbufCount++;
			}
#endif
*/
		}
		else if(inlen == 0)
		{
#ifdef	LOGFILE
			LogSave("ERROR: 服务器已经关闭!");
#endif
			Destroy();
			return false;
		}
		else	// len < 0
		{
			// 连接已断开或者错误(包括阻塞)
			int err = WSAGetLastError();
			if(err != WSAEWOULDBLOCK)
			{
#ifdef	LOGFILE
				LogSave("ERROR %d: recv failed.", err);
#endif
				Destroy();
				return false;
			}
		}
	}			// if(m_bState && m_nInbufLen < INBUFLEN)

	return true;

//内部函数	}catch(...){ LogSave("CATCH ERROR: RecvFromSock()."); exit(5); }
}

template <unsigned char a1, unsigned char b1, unsigned char c1, unsigned char fst1, 
			unsigned char a2, unsigned char b2, unsigned char c2, unsigned char fst2>
BOOL CGameSocket<a1, b1, c1, fst1, a2, b2, c2, fst2>::Flush(void)		//? 如果 OUTBUF > SENDBUF 则需要多次SEND()
{
	try{
		// 发送一段数据
		if(m_nOutbufLen > 0)
		{
			int	outsize;
			outsize = send(m_sockClient, m_bufOutput, m_nOutbufLen, 0);
			if(outsize > 0)
			{
	//				LogSave("发送了 %d 个字节", outsize);		//???
				// 删除已发送的部分
				if(m_nOutbufLen - outsize > 0)
					memcpy(m_bufOutput, m_bufOutput + outsize, m_nOutbufLen - outsize);
				m_nOutbufLen -= outsize;
				assert(m_nOutbufLen >= 0);
			}
			else	// 错误
			{
				int err = WSAGetLastError();
				if(err != WSAEWOULDBLOCK)
				{
#ifdef	LOGFILE
					LogSave("ERROR: 网络错误[%d],无法发送", err);
#endif
					Destroy();
					return false;
				}
			}
		}

		return true;

	}catch(...){
#ifdef	LOGFILE
		LogSave("CATCH ERROR: Flush().");
#endif
		exit(5);
	}
}

template <unsigned char a1, unsigned char b1, unsigned char c1, unsigned char fst1, 
			unsigned char a2, unsigned char b2, unsigned char c2, unsigned char fst2>
BOOL CGameSocket<a1, b1, c1, fst1, a2, b2, c2, fst2>::Check(void)
{
	try{
		// 检查状态
		if(m_bState)
		{
			char	buf[1];
			int	ret = recv(m_sockClient, buf, 1, MSG_PEEK);
			if(ret == 0)
			{
#ifdef	LOGFILE
				LogSave("ERROR: 服务器已经关闭.");
#endif
				Destroy();
				return false;
			}
			else if(ret < 0)
			{
				int err = WSAGetLastError();
				if(err != WSAEWOULDBLOCK)
				{
#ifdef	LOGFILE
					LogSave("ERROR %d: 网络错误.", err);
#endif
					Destroy();
					return false;
				}
				else	// 阻塞
				{
					return true;
				}
			}
			else	// 有数据
			{
				return true;
			}
		}
		else
		{
			return false;
		}

	}catch(...){
#ifdef	LOGFILE
		LogSave("CATCH ERROR: Check().");
#endif
		exit(5);
	}
}

template <unsigned char a1, unsigned char b1, unsigned char c1, unsigned char fst1, 
			unsigned char a2, unsigned char b2, unsigned char c2, unsigned char fst2>
void CGameSocket<a1, b1, c1, fst1, a2, b2, c2, fst2>::Destroy(void)
{
	try
	{
		// 关闭
		if(m_bState)
		{
			closesocket(m_sockClient);
			m_sockClient = INVALID_SOCKET;
			WSACleanup();
	//!!! 剩余消息可继续处理		m_nInbufLen = 0;
	//!!! 剩余消息可继续处理		m_nInbufStart = 0;
			m_nOutbufLen = 0;
			m_bState	= false;
		}

	}catch(...){
#ifdef	LOGFILE
		LogSave("CATCH ERROR: Destroy().");
#endif
		exit(5);
	}
}


///////////////////////////////////////////////////////////////////////////
//typedef	CGameSocket<0xB2, 0x9B, 0x53, 0xCF, 0xFC, 0xC9, 0xD9, 0xC6>	CAccountSocket;
//typedef	CGameSocket<0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00>	CAccountSocket;
typedef	CGameSocket<0x20, 0xFD, 0x07, 0x1F, 0x7A, 0xCF, 0xE5, 0x3F>	CLoginSocket;


#endif

⌨️ 快捷键说明

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