584 lines
12 KiB
C++
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();
|
|
}
|