Files
mir_server/server/RobotGate/CustomGateClient.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

584 lines
12 KiB
C++

#include "StdAfx.h"
CCustomGateClient::CCustomGateClient()
{
m_szSrvHost[0] = _T('\0');
m_szClientName[0] = _T('\0');
m_nSrvPort = 0;
m_bStoped = false;
m_bConnected = false;
m_hConnectThread = INVALID_HANDLE_VALUE;
m_hSendDataThread = INVALID_HANDLE_VALUE;
m_hRecvDataThread = INVALID_HANDLE_VALUE;
m_socket = INVALID_SOCKET;
m_SendMsgList.setLock(&m_SendMsgLock);
m_FreeMsgList.setLock(&m_FreeMsgLock);
m_RecvMsgList.setLock(&m_RecvMsgLock);
m_RecvFreeMsgList.setLock(&m_RecvFreeMsgLock);
ZeroMemory(&m_RecvMsg, sizeof(m_RecvMsg));
m_SendBigPacket.setAllocator(&m_Allocator);
}
CCustomGateClient::~CCustomGateClient()
{
Stop();
UnintSocketLib();
// 删除所有的数据包
DestroyPacketList(m_SendingPacketList);
DestroyPacketList(m_FreeMsgList);
DestroyPacketList(m_RecvMsgList);
DestroyPacketList(m_RecvFreeMsgList);
}
bool CCustomGateClient::Startup()
{
OutputMsg(rmTip, _T("CustomGateClient[%s] Start..."), m_szClientName);
Stop();
if (!InitSockLib())
return false;
m_bStoped = false;
// 创建连接线程
#ifdef _MSC_VER
m_hConnectThread = ::CreateThread(NULL, 0, staticConnectThreadRountine, this, 0, NULL);
#else
pthread_create(&m_hConnectThread, NULL, staticConnectThreadRountine, this);
#endif
if (m_hConnectThread != INVALID_HANDLE_VALUE)
{
#ifdef _MSC_VER
CloseHandle(m_hConnectThread);
#endif
}
else
{
OutputMsg(rmError, _T("%s Create Connect Thread Failed[errcode:%d]"), __FUNCTION__, GetLastError());
return false;
}
// 创建发送线程
#ifdef _MSC_VER
m_hSendDataThread = ::CreateThread(NULL, 0, staticSendDataThreadRountine, this, 0, NULL);
#else
pthread_create(&m_hSendDataThread, NULL, staticSendDataThreadRountine, this);
#endif
if (m_hSendDataThread != INVALID_HANDLE_VALUE)
{
#ifdef _MSC_VER
CloseHandle(m_hSendDataThread);
#endif
}
else
{
OutputMsg(rmError, _T("%s Create SendData Thread Failed[errcode:%d]"), __FUNCTION__, GetLastError());
return false;
}
// 创建接收数据线程
#ifdef _MSC_VER
m_hRecvDataThread = ::CreateThread(NULL, 0, staticRecvDataThreadRountine, this, 0, NULL);
#else
pthread_create(&m_hRecvDataThread, NULL, staticRecvDataThreadRountine, this);
#endif
if (m_hRecvDataThread != INVALID_HANDLE_VALUE)
{
#ifdef _MSC_VER
CloseHandle(m_hRecvDataThread);
#endif
}
else
{
OutputMsg(rmError, _T("%s Create SendData Thread Failed[errcode:%d]"), __FUNCTION__, GetLastError());
return false;
}
return true;
}
void CCustomGateClient::Stop()
{
m_bStoped = true;
Close();
Sleep(3000);
}
void CCustomGateClient::Close()
{
if (m_socket != INVALID_SOCKET)
{
closesocket(m_socket);
m_socket = INVALID_SOCKET;
}
if (m_bConnected)
{
m_bConnected = false;
// 清空缓存数据数据
m_RecvMsgList.flush();
m_RecvFreeMsgList.appendArray(m_RecvMsgList, m_RecvMsgList.count());
m_RecvMsgList.trunc(0);
m_SendingPacketList.flush();
m_FreeMsgList.appendArray(m_SendingPacketList, m_SendingPacketList.count());
m_SendingPacketList.trunc(0);
OutputMsg(rmTip, _T("与[%s]连接断开..."), m_szClientName);
}
OnClosed();
}
void CCustomGateClient::SendRegisteClient()
{
}
void CCustomGateClient::SendKeepAlive()
{
}
void CCustomGateClient::SendDataRoutine()
{
while (!m_bStoped)
{
// 如果已经连接上,发送数据
if (m_bConnected)
{
TICKCOUNT nStartTick = _getTickCount();
m_SendMsgList.flush();
INT_PTR nCount = m_SendMsgList.count();
if (nCount > 0)
{
for (INT_PTR i = 0; i < nCount; i++)
{
CDataPacket* packet = m_SendMsgList[i];
size_t nAvailableLen = packet->getAvaliableLength();
if (nAvailableLen > 0)
{
//if (!SendPointedData(packet->getOffsetPtr(), nAvailableLen)) // 发送数据出错,退出
// break;
m_SendBigPacket.writeBuf(packet->getOffsetPtr(), nAvailableLen);
}
}
// 采取打包的方式发送给服务器
m_SendBigPacket.setPosition(0);
INT_PTR nAvailableLen = m_SendBigPacket.getAvaliableLength();
if (nAvailableLen > 0)
{
SendPointedData(m_SendBigPacket.getOffsetPtr(), nAvailableLen);
m_SendBigPacket.setLength(0);
}
m_FreeMsgList.appendArray(m_SendMsgList, nCount);
m_SendMsgList.trunc(0);
}
Sleep(3);
}
else
{
Sleep(100);
}
}
}
bool CCustomGateClient::SendPointedData(const char* pData, size_t nLen)
{
DECLARE_FUN_TIME_PROF()
int nRet;
while (nLen > 0)
{
nRet = ::send(m_socket, pData, (int)nLen, 0);
if (SOCKET_ERROR == nRet)
{
Close();
return false;
}
pData += nRet;
nLen -= nRet;
}
return true;
}
void CCustomGateClient::RecvDataRoutine()
{
nPacketCount = 0;
while (!m_bStoped)
{
if (!m_bConnected)
{
Sleep(20);
continue;
}
// 读取消息头
bool bRet = ReadPointedData((char *)&(m_RecvMsg.header), sizeof(GATEMSGHDR));
if (!bRet)
{
OutputMsg(rmError, _T("Recv MsgHeader failed req=%d"), sizeof(GATEMSGHDR));
continue;
}
// 读取消息体
int nLen = m_RecvMsg.header.nDataSize;
if (m_RecvMsg.nBuffLen < nLen)
{
if (m_RecvMsg.data != NULL)
m_Allocator.FreeBuffer(m_RecvMsg.data);
m_RecvMsg.data = (char *)m_Allocator.AllocBuffer(nLen);
m_RecvMsg.nBuffLen = nLen;
}
bRet = ReadPointedData(m_RecvMsg.data, nLen);
if (!bRet)
{
OutputMsg(rmError, _T("Recv Msg Data Failed Req=%d"), nLen);
continue;
}
nPacketCount++;
// 拷贝数据到接收队列中, 不直接处理数据
CDataPacket* packet = AllocRecvPacket();
*packet << m_RecvMsg.header;
if (nLen > 0)
packet->writeBuf(m_RecvMsg.data, nLen);
*packet << (int)0xeeff;
packet->setPosition(0);
m_RecvMsgList.append(packet);
#ifdef _DEBUG
memset(&m_RecvMsg, 0, sizeof(m_RecvMsg));
#endif
//ProcessRecvBuffers(&m_RecvMsg);
}
}
bool CCustomGateClient::ReadPointedData(char* pBuff, size_t len)
{
DECLARE_FUN_TIME_PROF()
int nBytesRead;
while (len)
{
nBytesRead = recv(m_socket, pBuff, (int)len, 0);
if (nBytesRead <= 0)
{
Close();
return false;
}
pBuff += nBytesRead;
len -= nBytesRead;
}
return true;
}
void CCustomGateClient::PutMessage(int nIdent,
int nSessionIdx,
SOCKET nSocket,
int nServerIdx,
unsigned long long param,
char *pBuffer,
int nBufSize)
{
DECLARE_FUN_TIME_PROF()
if (!m_bConnected)
return;
//这个是消息头
RUNGATEMSGHDR Hdr;
Hdr.dwGateCode = RUNGATECODE;
Hdr.nSocket = nSocket;
Hdr.wSessionIdx = nSessionIdx;
Hdr.wIdent = nIdent;
Hdr.wServerIdx = nServerIdx;
Hdr.nDataSize = nBufSize;
Hdr.tickCount = param + _getTickCount();
SIZE_T headSize = sizeof(Hdr);
CDataPacket* packet = AllocPacket();
if (packet->getPosition() != 0)
{
OutputMsg(rmError, _T("-------------------------------"));
}
if (packet->getAvaliableLength() != 0)
{
OutputMsg(rmError, _T("--------------|||-----------------"));
}
packet->operator<<(Hdr);
if (nBufSize > 0)
{
packet->writeBuf(pBuffer, nBufSize);
}
packet->setPosition(0);
if (packet->getAvaliableLength() != sizeof(Hdr) + nBufSize)
{
OutputMsg(rmError, _T("--------------packet error[%d]--------------"), nBufSize);
}
m_SendMsgList.append(packet);
}
CDataPacket* CCustomGateClient::AllocPacket()
{
if (m_FreeMsgList.count() > 0)
{
CDataPacket* pkg = m_FreeMsgList.pop();
pkg->setLength(0);
return pkg;
}
if (m_FreeMsgList.appendCount() > 0)
m_FreeMsgList.flush();
if (m_FreeMsgList.count() <= 0 )
allocSendPacketList(m_FreeMsgList, 512);
CDataPacket* pkg = m_FreeMsgList.pop();
pkg->setLength(0);
return pkg;
}
CDataPacket* CCustomGateClient::AllocRecvPacket()
{
if (m_RecvFreeMsgList.count() > 0)
{
CDataPacket* pkg = m_RecvFreeMsgList.pop();
pkg->setLength(0);
return pkg;
}
if (m_RecvFreeMsgList.appendCount() > 0)
m_RecvFreeMsgList.flush();
if (m_RecvFreeMsgList.count() <= 0 )
allocSendPacketList(m_RecvFreeMsgList, 512);
CDataPacket* pkg = m_RecvFreeMsgList.pop();
pkg->setLength(0);
return pkg;
}
bool CCustomGateClient::CreateSocket()
{
if (m_socket != INVALID_SOCKET)
{
OutputMsg(rmError, _T("Socket is createdc already"));
return false;
}
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
return m_socket != INVALID_SOCKET ? true : false;
}
bool CCustomGateClient::ConnectToServerImpl()
{
int nErr;
TICKCOUNT dwCurTick = _getTickCount();
//创建套接字
if (INVALID_SOCKET == m_socket)
{
if (!CreateSocket())
{
OutputMsg(rmError, _T("[%s]Create Socket Failed"), __FUNCTION__);
return false;
}
}
hostent *phost;
#ifdef UNICODE
wylib::string::CWideString ws(addr);
wylib::string::CAnsiString *as = ws.toAStr();
phost = gethostbyname(*as);
delete as;
#else
phost = gethostbyname(m_szSrvHost);
#endif
if (phost)
{
in_addr addr;
addr.s_addr = *(u_long*)phost->h_addr_list[0];
SOCKADDR_IN addrin;
ZeroMemory(&addrin, sizeof(addrin));
addrin.sin_family = AF_INET;
addrin.sin_addr.s_addr = addr.s_addr;
addrin.sin_port = (htons((u_short)m_nSrvPort));
nErr = ::connect(m_socket, (sockaddr*)&addrin, sizeof(addrin));
if ( nErr == 0 )
{
OnConnected();
return true;
}
else
{
OutputMsg(rmNormal, _T("连接到%s服务器失败..."), m_szClientName);
return false;
}
}
else
{
OutputMsg(rmError, _T("GetHostByName resolve failed"));
return false;
}
return true;
}
void CCustomGateClient::OnConnected()
{
m_bConnected = true;
}
void CCustomGateClient::OnClosed()
{
}
void CCustomGateClient::ProcessRecvDataImpl()
{
DECLARE_FUN_TIME_PROF()
m_RecvMsgList.flush();
CDataPacket* packet;
INT_PTR nCount = m_RecvMsgList.count();
for (INT_PTR i = 0; i < nCount; i++)
{
packet = m_RecvMsgList[i];
GATEMSGHDR* pHeader = (GATEMSGHDR *)packet->getMemoryPtr();
ProcessRecvBuffers(pHeader, (LPCSTR)(pHeader+1), pHeader->nDataSize);
int *pVerify = (int *)((char *)pHeader + sizeof(GATEMSGHDR) + pHeader->nDataSize);
Assert(*pVerify == 0xeeff);
}
m_RecvFreeMsgList.appendArray(m_RecvMsgList, m_RecvMsgList.count());
m_RecvMsgList.trunc(0);
}
void CCustomGateClient::ConnectToServerRoutine()
{
TICKCOUNT dwReconnectTick = _getTickCount();
while (!m_bStoped)
{
if (m_bConnected)
{
ProcessRecvDataImpl();
Sleep(3);
}
else
{
// Try Connect To Server
if (_getTickCount() >= dwReconnectTick)
{
if (ConnectToServerImpl())
{
OutputMsg(rmNormal, _T("连接到服务器[%s]成功"), m_szClientName);
}
dwReconnectTick = _getTickCount() + 5000;
}
Sleep(200);
}
}
return;
}
void CCustomGateClient::SingleRun()
{
}
bool CCustomGateClient::InitSockLib()
{
#ifdef WIN32
WSADATA wsaData;
int nErr = WSAStartup(0x0202, &wsaData);
if (nErr != 0)
{
OutputMsg(rmError, _T("%s Init Socket Lib Failed, errcode=%d"), __FUNCTION__, nErr);
return false;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
OutputMsg(rmError, "Could not find a usable version[2.2] of Winsock.dll\n");
return false;
}
#endif
return true;
}
void CCustomGateClient::UnintSocketLib()
{
#ifdef WIN32
WSACleanup();
#endif
}
#ifdef _MSC_VER
DWORD CCustomGateClient::staticConnectThreadRountine(LPVOID pParam)
#else
void* CCustomGateClient::staticConnectThreadRountine(void* pParam)
#endif
{
CCustomGateClient* pThis = (CCustomGateClient *)pParam;
if (pThis)
pThis->ConnectToServerRoutine();
return 0;
}
#ifdef _MSC_VER
DWORD CCustomGateClient::staticSendDataThreadRountine(LPVOID pParam)
#else
void* CCustomGateClient::staticSendDataThreadRountine(void* pParam)
#endif
{
CCustomGateClient* pThis = (CCustomGateClient *)pParam;
if (pThis)
pThis->SendDataRoutine();
return 0;
}
#ifdef _MSC_VER
DWORD CCustomGateClient::staticRecvDataThreadRountine(LPVOID pParam)
#else
void* CCustomGateClient::staticRecvDataThreadRountine(void* pParam)
#endif
{
CCustomGateClient* pThis = (CCustomGateClient *)pParam;
if (pThis)
pThis->RecvDataRoutine();
return 0;
}
void CCustomGateClient::SetClientName(LPCTSTR sClientName)
{
_tcsncpy(m_szClientName, sClientName, ArrayCount(m_szClientName) - 1);
m_szClientName[ArrayCount(m_szClientName) - 1] = 0;
}
void CCustomGateClient::SetServerHost(LPCTSTR sHost)
{
_tcsncpy(m_szSrvHost, sHost, ArrayCount(m_szSrvHost) - 1);
m_szSrvHost[ArrayCount(m_szSrvHost) - 1] = 0;
}
void CCustomGateClient::SetServerPort(const INT_PTR nPort)
{
m_nSrvPort = nPort;
}
void CCustomGateClient::Dump()
{
OutputMsg(rmTip, _T("等待发送数据包数量: %d个\r\n"), (int)(m_SendMsgList.count() + m_SendMsgList.appendCount()));
}
void CCustomGateClient::DestroyPacketList(CQueueList<CDataPacket*>& pkgList)
{
if (pkgList.appendCount() > 0)
pkgList.flush();
for (INT_PTR i = pkgList.count()-1; i >= 0; i--)
{
CDataPacket* pkg = pkgList[i];
pkg->~CDataPacket();
}
pkgList.clear();
}