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

📄 mainctrl.cpp

📁 信使小精灵,是一个简易的聊天工具。主要是演示了网络编程的主要步骤。本程序使用封装好的函数库
💻 CPP
字号:
//mainCtrl.cpp
///////////////////////////////////////////////////////////////////////////////
#include "mainCtrl.h"
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static void HandleServerNetEvent(IN SOCKET hSocket, IN ETransportEvent eEvent, 
								 IN void *pDataBuf, IN unsigned long nDataLen, 
								 IN int nError, IN void *pContext)
{
	if( nError != TRANSPORT_OK ) return;

	CMainCtrl *pMainCtrl = (CMainCtrl *)pContext;
	if( NULL == pMainCtrl ) return;
	
	pMainCtrl->processNetEvent(hSocket, eEvent, pDataBuf, nDataLen);
}

///////////////////////////////////////////////////////////////////////////////
CMainCtrl::CMainCtrl()
{
	int nElementSize = sizeof(TUSER_GAME_INFO_STRU);
	m_tClientConnections.Init(nElementSize, "SERVERTUNNEL_CONNECTION_TABLE");
}

CMainCtrl::~CMainCtrl()
{
}

int CMainCtrl::StartServer()
{
	/*for Client, Port can be 0, 
	and for Server, Port is Listening Port*/
	unsigned short usPort = SERVER_PORT;
	int nResult = m_tServerTunnel.net_OpenSocket(Transport_Server, 
											usPort, 
											HandleServerNetEvent, this);
	if( TRANSPORT_OK != nResult )
	{
		printf("net_OpenSocket failed!\n");

		return nResult;
	}

	printf("Server is ready! Port = %d...\n", usPort);

	return TRANSPORT_OK;
}

int CMainCtrl::StopServer()
{
	printf("\nNow is Stopping Server, please wait...");

	int nResult = m_tServerTunnel.net_CloseSocket();

	m_tClientConnections.End();

	return nResult;
}

CTableInfoMgr *CMainCtrl::GetClientConnectionTable()
{
	return &m_tClientConnections;
}

///////////////////////////////////////////////////////////////////////////////
void CMainCtrl::processNetEvent(IN SOCKET hSocket, 
								IN ETransportEvent eEvent, 
								IN void *pRecvMsg, IN unsigned long nDataLen)
{
	unsigned long ulUserID = hSocket;

	if( Transport_AcceptEv == eEvent )
	{
		printf("Accept one new connection. Socket = %d\n", hSocket);
	}
	else if( Transport_ReadEv == eEvent )
	{
		if( NULL == pRecvMsg ) return;
		
		TMessageHeader* pHeader = (TMessageHeader *)pRecvMsg;
		char *pDataBuf = (char *)pRecvMsg + MESSAGE_HEADER_LEN;

		WORD dwMessageID = pHeader->wMessageId;
		switch(dwMessageID)
		{
		case MSG_LOGIN_REQ:
			{
				TLOGIN_STRU tLoginInfo = {0};
				memcpy(&tLoginInfo, pDataBuf, sizeof(TLOGIN_STRU));
				DWORD dwConnectionID = tLoginInfo.tCommonMsg.dwConnectionID;
				if( dwConnectionID != hSocket )
				{
					dwConnectionID = hSocket;
					tLoginInfo.tCommonMsg.dwConnectionID = dwConnectionID;
				}
				processLoginRequest(&tLoginInfo);
				
				break;
			}

		case MSG_CHATMESSAGE_REQ:
			{
				TCHAT_MESSAGE_STRU *pChatMessage = (TCHAT_MESSAGE_STRU *)pDataBuf;
				
				DWORD dwConnectionID = pChatMessage->tCommonMsg.dwConnectionID;
				if( dwConnectionID != hSocket )
				{
					dwConnectionID = hSocket;
					pChatMessage->tCommonMsg.dwConnectionID = dwConnectionID;
				}
				processChatMessageRequest((void *)pChatMessage);

				break;
			}
		}
	}
	else if( Transport_CloseEv == eEvent )
	{
		unsigned long ulUserID = hSocket;
		processDiconnection(ulUserID);		
	}
}

void CMainCtrl::processLoginRequest(void *pLoginInfo)
{
	if( NULL == pLoginInfo ) return;

	TLOGIN_STRU *ptLoginInfo = (TLOGIN_STRU *)pLoginInfo;

	DWORD dwUserID = ptLoginInfo->tCommonMsg.dwConnectionID;
	int nResult = VerifyUserLoginInfo((void *)ptLoginInfo);
	
	DWORD dwConnectionID = (LOGIN_RESULT_SUC == nResult) ? dwUserID : INVALID_SOCKET;
	WORD wMessageId = MSG_LOGIN_RESP;
	LOGIN_RESULT_STRU tLoginResult = {0};
	tLoginResult.tCommonMsg.dwConnectionID = dwConnectionID;
	tLoginResult.tCommonMsg.wMessageId = wMessageId;
	tLoginResult.byResult = nResult;
	tLoginResult.dwUserID = dwConnectionID;
	tLoginResult.byStatus = 
		(LOGIN_RESULT_SUC == nResult) ? USER_STATUS_ONLINE : USER_STATUS_OFFLINE;

	CTableInfoMgr *pConnectionTable = GetClientConnectionTable();
	long lCount = pConnectionTable->GetItemCount();
	tLoginResult.wUserCount = lCount;
	
	DWORD dwDataLen = sizeof(LOGIN_RESULT_STRU);
	TMessageHeader tHeader = {0};
	tHeader.wMessageId = wMessageId;
	tHeader.dwDataLen = dwDataLen;
	
	SOCKET hSocket = (SOCKET)dwUserID;
	m_tServerTunnel.net_Send(hSocket, &tHeader, (void *)&tLoginResult, dwDataLen);

	/*Send User Info*/
	TUSERLIST_INFO_STRU tUserListInfo = {0};

	dwDataLen = sizeof(TUSERLIST_INFO_STRU);
	memset(&tHeader, 0x00, sizeof(TMessageHeader));
	tHeader.wMessageId = MSG_USERINFO_RESP;
	tHeader.dwDataLen = dwDataLen;
	
	for(long lIndex = 0; lIndex < lCount; lIndex++)
	{
		TUSER_GAME_INFO_STRU *pUserInfo = (TUSER_GAME_INFO_STRU *)pConnectionTable->GetItemValue(lIndex);
		if( NULL == pUserInfo ) continue;

		memset(&tUserListInfo, 0x00, sizeof(TUSERLIST_INFO_STRU));
		tUserListInfo.dwConnectionID = pUserInfo->dwConnectionID;
		tUserListInfo.byStatus = pUserInfo->tUserInfo.byStatus;
		strcpy(tUserListInfo.szUserName, pUserInfo->tUserInfo.szUserName);

		if( dwUserID == pUserInfo->dwConnectionID )	/*The owner*/
		{
			sendMessageToAllUsers(&tHeader, (void *)&tUserListInfo, dwDataLen);
		}
		else	/*The Others*/
		{
			m_tServerTunnel.net_Send(hSocket, &tHeader, (void *)&tUserListInfo, dwDataLen);
		}
	}
}

void CMainCtrl::processDiconnection(unsigned long ulUserID)
{
	CTableInfoMgr *pConnectionTable = GetClientConnectionTable();
	TUSER_GAME_INFO_STRU *pUserInfo = (TUSER_GAME_INFO_STRU *)pConnectionTable->Find(ulUserID);
	if( NULL != pUserInfo )
	{
		TUSERLIST_INFO_STRU tUserListInfo = {0};

		DWORD dwDataLen = sizeof(TUSERLIST_INFO_STRU);
		TMessageHeader tHeader = {0};
		memset(&tHeader, 0x00, sizeof(TMessageHeader));
		tHeader.wMessageId = MSG_LOGOUT_RESP;
		tHeader.dwDataLen = dwDataLen;

		tUserListInfo.dwConnectionID = pUserInfo->dwConnectionID;
		tUserListInfo.byStatus = USER_STATUS_OFFLINE;
		strcpy(tUserListInfo.szUserName, pUserInfo->tUserInfo.szUserName);

		pConnectionTable->Delete(ulUserID);

		sendMessageToAllUsers(&tHeader, (void *)&tUserListInfo, dwDataLen);
	}

	printf("Disconnect one connection. Socket = %ld\n", ulUserID);
}

void CMainCtrl::processChatMessageRequest(void *pChatMessage)
{
	if( NULL == pChatMessage ) return;

	TCHAT_MESSAGE_STRU *ptChatMessage = (TCHAT_MESSAGE_STRU *)pChatMessage;
	DWORD dwUserID = ptChatMessage->tCommonMsg.dwConnectionID;
	
	int nMessageLen = ptChatMessage->wMessageLen;
	if( nMessageLen > 0 )
	{
		char *szChatMessage = new char[nMessageLen];
		memset(szChatMessage, 0x00, nMessageLen);
		memcpy(szChatMessage, ptChatMessage->byFileContent, nMessageLen);

		DWORD dwConnectionID = ptChatMessage->tCommonMsg.dwConnectionID;
		printf("Receive Message From %ld: %s\n", dwConnectionID, szChatMessage);
		
		delete [] szChatMessage;
		szChatMessage = NULL;

		unsigned long ulDataLen = sizeof(TCHAT_MESSAGE_STRU) + nMessageLen;
		WORD wMessageId = MSG_CHATMESSAGE_RESP;
		ptChatMessage->tCommonMsg.wMessageId = wMessageId;

		TMessageHeader tHeader = {0};
		tHeader.wMessageId = wMessageId;
		tHeader.dwDataLen = ulDataLen;

		DWORD dwFromUserID = ptChatMessage->dwFromUserID;
		DWORD dwToUserID = ptChatMessage->dwToUserID;
		if( INVALID_SOCKET != dwToUserID )	/*Send to one user*/
		{
			CTableInfoMgr *pConnectionTable = GetClientConnectionTable();
			TUSER_GAME_INFO_STRU *pUserInfo = (TUSER_GAME_INFO_STRU *)pConnectionTable->Find(dwToUserID);
			if( NULL != pUserInfo )	/*Send to To User*/
			{
				SOCKET hSocket = (SOCKET)dwToUserID;
				m_tServerTunnel.net_Send(hSocket, &tHeader, (void *)ptChatMessage, ulDataLen);

				/*Echo to From User*/
				hSocket = (SOCKET)dwUserID;
				m_tServerTunnel.net_Send(hSocket, &tHeader, (void *)ptChatMessage, ulDataLen);
			}
		}
		else	/*Send to all users*/
		{
			sendMessageToAllUsers(&tHeader, (void *)ptChatMessage, ulDataLen);			
		}
	}
}

void CMainCtrl::sendMessageToAllUsers(void *pHeader, 
									  void *pDataBuf, unsigned long ulDataLen)
{
	if( (NULL == pHeader) || (NULL == pDataBuf) || (0 >= ulDataLen) ) return;

	CTableInfoMgr *pConnectionTable = GetClientConnectionTable();
	long lCount = pConnectionTable->GetItemCount();
	for(long lIndex = 0; lIndex < lCount; lIndex++)
	{
		TUSER_GAME_INFO_STRU *pUserInfo = (TUSER_GAME_INFO_STRU *)pConnectionTable->GetItemValue(lIndex);
		if( NULL == pUserInfo ) continue;

		SOCKET hSocket = (SOCKET)pUserInfo->dwConnectionID;
		m_tServerTunnel.net_Send(hSocket, pHeader, pDataBuf, ulDataLen);
	}
}

///////////////////////////////////////////////////////////////////////////////
int CMainCtrl::VerifyUserLoginInfo(void *pLoginInfo)
{
	int nResult = LOGIN_RESULT_SUC;

	if( NULL == pLoginInfo )
	{
		return LOGIN_RESULT_FAILED;
	}

	TLOGIN_STRU *ptLoginInfo = (TLOGIN_STRU *)pLoginInfo;
	DWORD dwUserID = ptLoginInfo->tCommonMsg.dwConnectionID;

	/*verify the user information*/
	CTableInfoMgr *pConnectionTable = GetClientConnectionTable();
	long lCount = pConnectionTable->GetItemCount();
	for(long lIndex = 0; lIndex < lCount; lIndex++)
	{
		TUSER_GAME_INFO_STRU *pUserInfo = (TUSER_GAME_INFO_STRU *)pConnectionTable->GetItemValue(lIndex);
		if( NULL == pUserInfo ) continue;

		if( (0 == stricmp(pUserInfo->tUserInfo.szUserName, ptLoginInfo->tUserInfo.szUserName)) 
			&& (USER_STATUS_ONLINE == pUserInfo->tUserInfo.byStatus) )
		{
			return LOGIN_RESULT_MULTI;
		}
	}

	TUSER_GAME_INFO_STRU *pUserGameInfo = new TUSER_GAME_INFO_STRU;
	memset(pUserGameInfo, 0x00, sizeof(TUSER_GAME_INFO_STRU));
	
	pUserGameInfo->dwConnectionID = dwUserID;
	pUserGameInfo->tUserInfo.dwUserID = dwUserID;
	strcpy(pUserGameInfo->tUserInfo.szUserName, ptLoginInfo->tUserInfo.szUserName);
	strcpy(pUserGameInfo->tUserInfo.szPassword, ptLoginInfo->tUserInfo.szPassword);
	pUserGameInfo->tUserInfo.byStatus = USER_STATUS_ONLINE;
	
	pConnectionTable->Add(pUserGameInfo->dwConnectionID, (void *)pUserGameInfo);
	
	return nResult;
}

///////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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