Files
SimpleRemoter/server/2015Remote/proxy/ProxyConnectServer.cpp
2025-10-19 09:04:27 +02:00

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);
}