#include "StdAfx.h" #include "ServerPtr.h" #include "OnlineUser.h" #include #include "CritSection.h" #include "msg.pb.h" #include "table.pb.h" time_t g_systm; // 服务通信对象; CServerPtr* CServerPtr::m_spThis = NULL; CServerPtr::CServerPtr(void) { // 创建监听器对象 m_pListener = ::Create_HP_TcpServerListener(); // 创建 Socket 对象 m_pServer = ::Create_HP_TcpPackServer(m_pListener); // 设置 Socket 监听器回调函数 ::HP_Set_FN_Server_OnPrepareListen(m_pListener, OnPrepareListen); ::HP_Set_FN_Server_OnAccept(m_pListener, OnAccept); ::HP_Set_FN_Server_OnSend(m_pListener, OnSend); ::HP_Set_FN_Server_OnReceive(m_pListener, OnReceive); ::HP_Set_FN_Server_OnClose(m_pListener, OnClose); ::HP_Set_FN_Server_OnShutdown(m_pListener, OnShutdown); // 获取机器时间; time(&g_systm); // g_systm = time(NULL); } CServerPtr::~CServerPtr(void) { // 销毁 Socket 对象 ::Destroy_HP_TcpPackServer(m_spThis->m_pServer); // 销毁监听器对象 ::Destroy_HP_TcpServerListener(m_pListener); } void CServerPtr::Release() { if (m_spThis) delete m_spThis; m_spThis = NULL; } BOOL CServerPtr::Start() { if (m_spThis == NULL) return FALSE; ::HP_TcpPackServer_SetMaxPackSize(m_spThis->m_pServer, 0x3FFFFF); ::HP_TcpPackServer_SetPackHeaderFlag(m_spThis->m_pServer, 0x3FE); if (::HP_Server_Start(m_spThis->m_pServer, _T("0.0.0.0"), Global::g_dwSvrPort)) { //::LogServerStart(ADDRESS, PORT); OutputDebugString(_T("服务器启动成功!\n")); //SetAppState(ST_STARTED); } else { //::LogServerStartFail(::HP_Server_GetLastError(m_spThis->m_pServer), ::HP_Server_GetLastErrorDesc(m_spThis->m_pServer)); OutputDebugString(_T("服务器启动失败!\n")); //SetAppState(ST_STOPPED); } return TRUE; } BOOL CServerPtr::Stop() { if (::HP_Server_Stop(m_spThis->m_pServer)) { OutputDebugString(_T("停止服务器成功!\n")); ::LogServerStop(); //SetAppState(ST_STOPPED); } else { ASSERT(FALSE); } return TRUE; } BOOL CServerPtr::Disconnect(IN const DWORD& dwConnId) { if (::HP_Server_Disconnect(m_spThis->m_pServer, dwConnId, TRUE)) { // 移除登录的用户信息; COnlineUser::GetInstance()->EraseOnlineUser(dwConnId); ::LogDisconnect(dwConnId); } else { ::LogDisconnectFail(dwConnId); } return TRUE; } En_HP_HandleResult CServerPtr::OnPrepareListen(HP_Server pSender,SOCKET soListen) { TCHAR szAddress[40]; int iAddressLen = sizeof(szAddress) / sizeof(TCHAR); USHORT usPort; ::HP_Server_GetListenAddress(pSender, szAddress, &iAddressLen, &usPort); ::PostOnPrepareListen(szAddress, usPort); return HR_OK; } En_HP_HandleResult CServerPtr::OnAccept(HP_Server pSender, HP_CONNID dwConnID, SOCKET soClient) { BOOL bPass = TRUE; TCHAR szAddress[40]; int iAddressLen = sizeof(szAddress) / sizeof(TCHAR); USHORT usPort; ::HP_Server_GetRemoteAddress(pSender, dwConnID, szAddress, &iAddressLen, &usPort); if (!m_spThis->m_strAddress.IsEmpty()) { if (m_spThis->m_strAddress.CompareNoCase(szAddress) == 0) bPass = FALSE; } //::PostOnAccept(dwConnID, szAddress, usPort, bPass); TRACE(_T("新客户端连接:%d, %s, %d!\n"), dwConnID, szAddress, usPort); return bPass ? HR_OK : HR_ERROR; } En_HP_HandleResult CServerPtr::OnSend(HP_Server pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength) { TRACE(_T("发送数据给客户端:%d, %s, %d!\n"), dwConnID, pData, iLength); //::PostOnSend(dwConnID, pData, iLength); return HR_OK; } En_HP_HandleResult CServerPtr::OnReceive(HP_Server pSender, HP_CONNID dwConnID, const BYTE* pData, int iLength) { TheProPackage thepackage; memcpy(&thepackage, pData, sizeof(TheProPackage)); EnHandleResult nResult = HR_OK; BYTE *pSendData = NULL; DWORD dwSendLen = 0; switch (thepackage.nCmd) { // 客户端请求登录; case C2CCMD_REQ_LOGIN: { Req_Login(dwConnID, pData, iLength, thepackage, pSendData, dwSendLen); } break; // 客户端请求登出; case C2CCMD_REQ_LOGOUT: { Req_LogOut(dwConnID, pData, iLength, thepackage, pSendData, dwSendLen); } break; // 客户端请求添加部门; case C2CCMD_NEW_DEPARTMENT: { New_Department(dwConnID, pData, iLength, thepackage, pSendData, dwSendLen); } break; // 客户端请求删除部门; case C2CCMD_DEL_DEPARTMENT: { Del_Department(dwConnID, pData, iLength, thepackage, pSendData, dwSendLen); } break; // 客户端请求修改部门; case C2CCMD_MOD_DEPARTMENT: { // 暂未使用; Mod_Department(dwConnID, pData, iLength, thepackage, pSendData, dwSendLen); } break; // 客户端请求查询部门; case C2CCMD_QRY_DEPARTMENT: { nResult = Ask_Department(dwConnID, pData, iLength, thepackage, pSendData, dwSendLen); if (nResult != HR_IGNORE) return nResult; } break; ////////////////////////////////////////////////////////////////////////// default: break; } BOOL bSendResult = ::HP_Server_Send(pSender, dwConnID, pSendData, dwSendLen); if (pSendData) delete[]pSendData; return bSendResult ? HR_OK : HR_ERROR; } En_HP_HandleResult CServerPtr::OnClose(HP_Server pSender, HP_CONNID dwConnID, En_HP_SocketOperation enOperation, int iErrorCode) { // 移除登录的用户信息; COnlineUser::GetInstance()->EraseOnlineUser(dwConnID); iErrorCode == SE_OK ? ::PostOnClose(dwConnID) : ::PostOnError(dwConnID, enOperation, iErrorCode); return HR_OK; } En_HP_HandleResult CServerPtr::OnShutdown(HP_Server pSender) { ::PostOnShutdown(); return HR_OK; } ////////////////////////////////////////////////////////////////////////// void CServerPtr::Req_Login(IN HP_CONNID dwConnID, IN const BYTE* pReceiveData, IN INT nReceiveLength, IN TheProPackage &thepackage, OUT BYTE*& pSendData, OUT DWORD &dwSendLen) { if (COnlineUser::GetInstance()->IsAccountExist(thepackage.szStudioId, thepackage.szAccount) == -1) {// 用户没在线; // 查询数据库是否存在用户; INT nRet = USER_NULL; //CUserDetail tagUserDetail; //nRet = g_pODBCPool->QueryUserDetail(thepackage.szStudioId, thepackage.szAccount, thepackage.szPassword, &tagUserDetail); nRet = 0; if (nRet == USER_LOGIN) { CMemFile mf; CArchive ar(&mf, CArchive::store); //tagUserDetail.Serialize(ar); ar.Close(); DWORD dwArchive = mf.GetLength(); dwSendLen = sizeof(TheProPackage) - 2 + dwArchive; pSendData = new BYTE[dwSendLen]; TheProPackage *pPackage = (TheProPackage*)pSendData; pPackage->flag = PACKAGE_ONESELF; pPackage->nCmd = thepackage.nCmd; pPackage->nDataLen = dwArchive; pPackage->dwReserve = USER_LOGIN; BYTE *pMf = mf.Detach(); memcpy(pPackage->byBody, pMf, dwArchive); if (pMf) delete pMf; // 记录在线用户; COnlineUser::GetInstance()->InsertOnlineUser(dwConnID, thepackage.szStudioId, thepackage.szAccount); } else { dwSendLen = sizeof(TheProPackage); pSendData = new BYTE[dwSendLen]; TheProPackage *pPackage = (TheProPackage*)pSendData; pPackage->flag = PACKAGE_ONESELF; pPackage->nCmd = C2CCMD_REQ_LOGIN; pPackage->nDataLen = 0; pPackage->dwReserve = nRet; OutputDebugString(_T("用户密码不对\n")); } } else { dwSendLen = sizeof(TheProPackage); pSendData = new BYTE[dwSendLen]; TheProPackage *pPackage = (TheProPackage*)pSendData; pPackage->flag = PACKAGE_ONESELF; pPackage->nCmd = C2CCMD_REQ_LOGIN; pPackage->nDataLen = 0; pPackage->dwReserve = USER_HAVE_LOGIN; OutputDebugString(_T("用户已登录\n")); } } void CServerPtr::Req_LogOut(IN HP_CONNID dwConnID, IN const BYTE* pReceiveData, IN INT nReceiveLength, IN TheProPackage &thepackage, OUT BYTE*& pSendData, OUT DWORD &dwSendLen) { } void CServerPtr::New_Department(IN HP_CONNID dwConnID, IN const BYTE* pReceiveData, IN INT nReceiveLength, IN TheProPackage &thepackage, OUT BYTE*& pSendData, OUT DWORD &dwSendLen) { /*CMemFile mf; //mf.Attach(thepackage.szBody, thepackage.nDataLen);//错误方式; mf.Attach(const_cast(pReceiveData)+sizeof(TheProPackage) - 2, thepackage.nDataLen); CArchive ar(&mf, CArchive::load); CAddDepartment tagAddDepartment; tagAddDepartment.Serialize(ar); ar.Close(); mf.Detach(); CString strSQL; strSQL.Format(_T("INSERT INTO [DepartmentInfo](") _T("[StudioID], [DepartmentName], [DepartmentNote]) values ('%s', '%s', '%s')"), thepackage.szStudioId, tagAddDepartment.m_strDepartmentName, tagAddDepartment.m_strDepartmentNote); BOOL bRet = g_pODBCPool->ExecuteSQL(strSQL); // 返回信息; dwSendLen = sizeof(TheProPackage); pSendData = new BYTE[dwSendLen]; TheProPackage *pPackage = (TheProPackage*)pSendData; pPackage->flag = PACKAGE_ONESELF; pPackage->nCmd = thepackage.nCmd; pPackage->nDataLen = 0; pPackage->dwReserve = bRet;*/ } void CServerPtr::Del_Department(IN HP_CONNID dwConnID, IN const BYTE* pReceiveData, IN INT nReceiveLength, IN TheProPackage &thepackage, OUT BYTE*& pSendData, OUT DWORD &dwSendLen) { /*CMemFile mf; //mf.Attach(thepackage.szBody, thepackage.nDataLen);//错误方式; mf.Attach(const_cast(pReceiveData)+sizeof(TheProPackage) - 2, thepackage.nDataLen); CArchive ar(&mf, CArchive::load); CAddDepartment tagAddDepartment; tagAddDepartment.Serialize(ar); ar.Close(); mf.Detach(); CString strSQL; strSQL.Format(_T("DELETE FROM [DepartmentInfo] WHERE [StudioID] = '%s' and [DepartmentName] = '%s' "), thepackage.szStudioId, tagAddDepartment.m_strDepartmentName); BOOL bRet = g_pODBCPool->ExecuteSQL(strSQL); // 返回信息; dwSendLen = sizeof(TheProPackage); pSendData = new BYTE[dwSendLen]; TheProPackage *pPackage = (TheProPackage*)pSendData; pPackage->flag = PACKAGE_ONESELF; pPackage->nCmd = thepackage.nCmd; pPackage->nDataLen = 0; pPackage->dwReserve = bRet;*/ } void CServerPtr::Mod_Department(IN HP_CONNID dwConnID, IN const BYTE* pReceiveData, IN INT nReceiveLength, IN TheProPackage &thepackage, OUT BYTE*& pSendData, OUT DWORD &dwSendLen) { } EnHandleResult CServerPtr::Ask_Department(IN HP_CONNID dwConnID, IN const BYTE* pReceiveData, IN INT nReceiveLength, IN TheProPackage &thepackage, OUT BYTE*& pSendData, OUT DWORD &dwSendLen) { CObList tagDpmList; INT nRet = 0; CMemFile mf; CArchive ar(&mf, CArchive::store); tagDpmList.Serialize(ar); ar.Close(); // 删除列表对象; POSITION pos = tagDpmList.GetHeadPosition(); while (pos) { LPVOID *pdpmObj = NULL; if (pdpmObj) delete pdpmObj; } tagDpmList.RemoveAll(); BOOL bResult = FALSE; __int64 nArchive = mf.GetLength(); if ((nArchive + sizeof(TheProPackage) - 2) > 0x3FFFFF) { __int64 nSubLen = nArchive; BYTE *pMf = mf.Detach(); while (nSubLen > 0) { if (nSubLen - 0x3FFFFF + sizeof(TheProPackage) - 2 > 0) dwSendLen = 0x3FFFFF; else dwSendLen = nSubLen + sizeof(TheProPackage) - 2; pSendData = new BYTE[dwSendLen]; TheProPackage *pPackage = (TheProPackage*)pSendData; pPackage->flag = PACKAGE_MULTIPLE; pPackage->nCmd = thepackage.nCmd; pPackage->nDataLen = nArchive; pPackage->nSubDataLen = (nSubLen - 0x3FFFFF + sizeof(TheProPackage) - 2) > 0 ? (0x3FFFFF - sizeof(TheProPackage) + 2) : nSubLen; pPackage->dwReserve = nRet; memcpy(pPackage->byBody, pMf + nArchive - nSubLen, pPackage->nSubDataLen); nSubLen -= (0x3FFFFF - sizeof(TheProPackage) + 2); bResult = ::HP_Server_Send(m_spThis->m_pServer, dwConnID, pSendData, dwSendLen); if (pSendData) delete[]pSendData; pSendData = NULL; if (!bResult) { if (pMf) delete pMf; return HR_ERROR; } } if (pMf) delete pMf; return HR_OK; } else {// 单包; dwSendLen = sizeof(TheProPackage) - 2 + nArchive; pSendData = new BYTE[dwSendLen]; TheProPackage *pPackage = (TheProPackage*)pSendData; pPackage->flag = PACKAGE_ONESELF; pPackage->nCmd = thepackage.nCmd; pPackage->nDataLen = nArchive; pPackage->dwReserve = nRet; BYTE *pMf = mf.Detach(); memcpy(pPackage->byBody, pMf, nArchive); if (pMf) delete pMf; } return HR_IGNORE; }