222 lines
6.4 KiB
C++
222 lines
6.4 KiB
C++
#include "stdafx.h"
|
|
#include "ProxyConnectServer.h"
|
|
|
|
#define MAX_SEND_BUFFER 65535 // 最大发送数据长度 1024*64
|
|
#define MAX_RECV_BUFFER 65535 // 最大接收数据长度
|
|
|
|
CProxyConnectServer::CProxyConnectServer(void) :m_TcpServer(this)
|
|
{
|
|
Mprintf("CProxyConnectServer\r\n");
|
|
m_bIsRun = TRUE;
|
|
m_dwIndex = 0;
|
|
memset(m_IDs, 0, sizeof(m_IDs));
|
|
}
|
|
|
|
|
|
CProxyConnectServer::~CProxyConnectServer(void)
|
|
{
|
|
if (m_TcpServer->GetState() != SS_STOPPED)
|
|
m_TcpServer->Stop();
|
|
while (m_TcpServer->GetState() != SS_STOPPED) {
|
|
Sleep(300);
|
|
}
|
|
Mprintf("~CProxyConnectServer\r\n");
|
|
}
|
|
|
|
BOOL CProxyConnectServer::Initialize(NOTIFYPROC pNotifyProc, void*user, int nMaxConnections, int nPort)
|
|
{
|
|
m_nMaxConnection = nMaxConnections;
|
|
m_TcpServer->SetMaxConnectionCount(nMaxConnections);
|
|
m_TcpServer->SetSendPolicy(SP_DIRECT);
|
|
m_TcpServer->SetNoDelay(TRUE);
|
|
m_pNotifyProc = pNotifyProc;
|
|
m_pUser = user;
|
|
m_nPort = nPort;
|
|
m_bStop = FALSE;
|
|
return m_TcpServer->Start(_T("0.0.0.0"), nPort);
|
|
}
|
|
|
|
EnHandleResult CProxyConnectServer::OnPrepareListen(ITcpServer* pSender, SOCKET soListen)
|
|
{
|
|
SYS_SSO_SendBuffSize(soListen, MAX_SEND_BUFFER);
|
|
SYS_SSO_RecvBuffSize(soListen, MAX_RECV_BUFFER);
|
|
return HR_OK;
|
|
}
|
|
|
|
EnHandleResult CProxyConnectServer::OnAccept(ITcpServer* pSender, CONNID dwConnID, UINT_PTR soClient)
|
|
{
|
|
if (!m_bIsRun)return HR_ERROR;
|
|
|
|
ClientContext* pContext = NULL;
|
|
{
|
|
m_Locker.lock();
|
|
if (!m_listFreePool.IsEmpty()) {
|
|
pContext = m_listFreePool.RemoveHead();
|
|
} else {
|
|
pContext = new(std::nothrow) ClientContext;
|
|
}
|
|
m_Locker.unlock();
|
|
}
|
|
if (pContext == NULL)
|
|
return HR_ERROR;
|
|
|
|
pContext->InitMember(dwConnID, nullptr);
|
|
pContext->m_Socket = dwConnID;
|
|
char szAddress[64] = {};
|
|
int iAddressLen = sizeof(szAddress);
|
|
USHORT usPort = 0;
|
|
pSender->GetRemoteAddress(dwConnID, szAddress, iAddressLen, usPort);
|
|
Mprintf("CProxyConnectServer: new connection %s:%d\n", szAddress, usPort);
|
|
pContext->ID = dwConnID;
|
|
m_TcpServer->SetConnectionExtra(dwConnID, pContext);
|
|
m_pNotifyProc(m_pUser, pContext, NC_CLIENT_CONNECT);
|
|
return HR_OK;
|
|
}
|
|
|
|
EnHandleResult CProxyConnectServer::OnSend(ITcpServer* pSender, CONNID dwConnID, const BYTE* pData, int iLength)
|
|
{
|
|
return HR_OK;
|
|
}
|
|
|
|
EnHandleResult CProxyConnectServer::OnReceive(ITcpServer* pSender, CONNID dwConnID, int iLength)
|
|
{
|
|
ClientContext* pContext = NULL;
|
|
if ((!m_TcpServer->GetConnectionExtra(dwConnID, (PVOID*)&pContext)) && (pContext != nullptr) && (iLength <= 0))
|
|
return HR_ERROR;
|
|
|
|
PBYTE pData = new BYTE[iLength];
|
|
m_TcpServer->Fetch(dwConnID, pData, iLength);
|
|
pContext->InDeCompressedBuffer.ClearBuffer();
|
|
BYTE bToken = COMMAND_PROXY_DATA;
|
|
pContext->InDeCompressedBuffer.Write(&bToken, sizeof(bToken));
|
|
pContext->InDeCompressedBuffer.Write((LPBYTE)&pContext->ID, sizeof(DWORD));
|
|
pContext->InDeCompressedBuffer.Write((PBYTE)pData, iLength);
|
|
SAFE_DELETE_ARRAY(pData);
|
|
m_pNotifyProc(m_pUser, pContext, NC_RECEIVE);
|
|
return HR_OK;
|
|
}
|
|
|
|
EnHandleResult CProxyConnectServer::OnClose(ITcpServer* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode)
|
|
{
|
|
ClientContext* pContext = NULL;
|
|
if (m_TcpServer->GetConnectionExtra(dwConnID, (PVOID*)&pContext) && pContext != nullptr)
|
|
m_TcpServer->SetConnectionExtra(dwConnID, NULL);
|
|
if (!pContext)
|
|
return HR_OK;
|
|
|
|
m_pNotifyProc(m_pUser, pContext, NC_CLIENT_DISCONNECT);
|
|
pContext->InCompressedBuffer.ClearBuffer();
|
|
pContext->InDeCompressedBuffer.ClearBuffer();
|
|
pContext->OutCompressedBuffer.ClearBuffer();
|
|
m_Locker.lock();
|
|
m_listFreePool.AddTail(pContext);
|
|
m_Locker.unlock();
|
|
return HR_OK;
|
|
}
|
|
|
|
EnHandleResult CProxyConnectServer::OnShutdown(ITcpServer* pSender)
|
|
{
|
|
return HR_OK;
|
|
}
|
|
|
|
|
|
BOOL CProxyConnectServer::Send(ClientContext* pContext, LPBYTE lpData, UINT nSize)
|
|
{
|
|
if (pContext == NULL)
|
|
return FALSE;
|
|
|
|
BOOL rt = FALSE;;
|
|
if (nSize > 0 && m_bIsRun) {
|
|
pContext->OutCompressedBuffer.Write(lpData, nSize);
|
|
rt = SendWithSplit(pContext->m_Socket, pContext->OutCompressedBuffer.GetBuffer(0),
|
|
pContext->OutCompressedBuffer.GetBufferLength(), MAX_SEND_BUFFER);
|
|
pContext->OutCompressedBuffer.ClearBuffer();
|
|
}
|
|
return rt;
|
|
}
|
|
|
|
|
|
BOOL CProxyConnectServer::SendWithSplit(CONNID dwConnID, LPBYTE lpData, UINT nSize, UINT nSplitSize)
|
|
{
|
|
int nSend = 0;
|
|
UINT nSendRetry = 0;
|
|
BOOL rt = TRUE;
|
|
if (nSize >= nSplitSize) {
|
|
UINT i = 0;
|
|
nSendRetry = nSize / nSplitSize;
|
|
for (i = 0; i < nSendRetry; i++) {
|
|
rt = m_TcpServer->Send(dwConnID, lpData, nSplitSize);
|
|
if (!rt)
|
|
return rt;
|
|
lpData += nSplitSize;
|
|
nSend += nSplitSize;
|
|
}
|
|
if (nSize - nSend < nSplitSize) {
|
|
if (nSize - nSend > 0) {
|
|
rt = m_TcpServer->Send(dwConnID, lpData, nSize - nSend);
|
|
if (!rt)
|
|
return rt;
|
|
}
|
|
}
|
|
} else {
|
|
rt = m_TcpServer->Send(dwConnID, lpData, nSize);
|
|
if (!rt)
|
|
return rt;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void CProxyConnectServer::Shutdown()
|
|
{
|
|
DWORD dwCount = 65535;
|
|
CONNID *pIDs = new CONNID[dwCount]();
|
|
BOOL status = m_TcpServer->GetAllConnectionIDs(pIDs, dwCount);
|
|
if (status && (dwCount > 0)) {
|
|
for (DWORD i = 0; i < dwCount; i++) {
|
|
Disconnect(pIDs[i]);
|
|
}
|
|
}
|
|
m_TcpServer->Stop();
|
|
m_bIsRun = FALSE;
|
|
while (m_TcpServer->GetState() != SS_STOPPED)
|
|
Sleep(10);
|
|
|
|
m_Locker.lock();
|
|
while (!m_listFreePool.IsEmpty())
|
|
delete m_listFreePool.RemoveTail();
|
|
m_Locker.unlock();
|
|
|
|
SAFE_DELETE_ARRAY(pIDs);
|
|
}
|
|
|
|
void CProxyConnectServer::ClearClient()
|
|
{
|
|
DWORD dwCount = 65535;
|
|
CONNID* pIDs = new CONNID[dwCount]();
|
|
BOOL status = m_TcpServer->GetAllConnectionIDs(pIDs, dwCount);
|
|
if (status && (dwCount > 0)) {
|
|
for (DWORD i = 0; i < dwCount; i++) {
|
|
m_TcpServer->Disconnect(pIDs[i]);
|
|
}
|
|
}
|
|
|
|
SAFE_DELETE_ARRAY(pIDs);
|
|
}
|
|
|
|
BOOL CProxyConnectServer::Disconnect(CONNID dwConnID)
|
|
{
|
|
m_TcpServer->Disconnect(dwConnID);
|
|
return 0;
|
|
}
|
|
|
|
BOOL CProxyConnectServer::IsConnected(CONNID dwConnID)
|
|
{
|
|
return m_TcpServer->IsConnected(dwConnID);
|
|
}
|
|
|
|
BOOL CProxyConnectServer::IsOverMaxConnectionCount()
|
|
{
|
|
return (m_TcpServer->GetConnectionCount() > (DWORD)m_nMaxConnection);
|
|
}
|