최종완료보고 버전
This commit is contained in:
@@ -0,0 +1,511 @@
|
||||
#ifndef MULTIPLEX_TRANSPORT__H_
|
||||
#define MULTIPLEX_TRANSPORT__H_
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class HMultiplexTransportTcpSocket;
|
||||
|
||||
|
||||
class HMultiplexTransport : public HTransport
|
||||
{
|
||||
public:
|
||||
HMultiplexTransport() {}
|
||||
~HMultiplexTransport() {}
|
||||
|
||||
inline void SetMpSocket(HMultiplexTcpSocket * pSocket) { m_pMulplexTransportSocket = pSocket; }
|
||||
inline HMultiplexTcpSocket * GetMpSocket() { return m_pMulplexTransportSocket; }
|
||||
|
||||
inline bool GetTransportInfo(const char * pName, void * pValue);
|
||||
|
||||
inline void Terminate();
|
||||
|
||||
inline int Send(const char * pData, int nSize);
|
||||
|
||||
protected:
|
||||
HMultiplexTcpSocket * m_pMulplexTransportSocket;
|
||||
|
||||
|
||||
friend class HMultiplexTransportTcpSocket;
|
||||
friend class HMultiplexTransportSslSocket;
|
||||
};
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
class HMultiplexTransportTcpSocket : public HMultiplexTcpSocket
|
||||
{
|
||||
public:
|
||||
HMultiplexTransportTcpSocket()
|
||||
{
|
||||
m_bAutoDelete = false;
|
||||
m_nReconnectTime = 0;
|
||||
m_pReceiveBuffer = (char *)malloc(g_nSocketReceiveBlockSize + 1);
|
||||
m_pTransport = NULL;
|
||||
}
|
||||
|
||||
HMultiplexTransportTcpSocket(SOCKET sock, struct sockaddr_in * psaiRemote, HMpsDispatcher * pDispatcher)
|
||||
: HMultiplexTcpSocket(sock, psaiRemote, pDispatcher)
|
||||
{
|
||||
m_bAutoDelete = false;
|
||||
m_nReconnectTime = 0;
|
||||
m_pReceiveBuffer = (char *)malloc(g_nSocketReceiveBlockSize + 1);
|
||||
m_pTransport = NULL;
|
||||
}
|
||||
|
||||
~HMultiplexTransportTcpSocket()
|
||||
{
|
||||
if (m_pTransport)
|
||||
delete m_pTransport;
|
||||
|
||||
free(m_pReceiveBuffer);
|
||||
}
|
||||
|
||||
inline void AttachTransport(HMultiplexTransport * pTransport) { m_pTransport = pTransport; }
|
||||
inline HMultiplexTransport * GetTransport() { return m_pTransport; }
|
||||
|
||||
inline void SetAutoDelete(bool bAutoDelete) { m_bAutoDelete = bAutoDelete; }
|
||||
inline void SetAutoReconnect(DWORD nTime) { m_nReconnectTime = nTime; }
|
||||
|
||||
protected:
|
||||
inline void OnClose()
|
||||
{
|
||||
if (m_bAutoDelete)
|
||||
SetState(MPS_DELETE); // auto delete
|
||||
else if (m_nReconnectTime > 0)
|
||||
SetTimer(2181006, m_nReconnectTime);
|
||||
|
||||
m_pTransport->OnReceivedStatus(HTransport::T_END_TRANSPORT);
|
||||
}
|
||||
|
||||
inline void OnConnect(bool bIsSuccess)
|
||||
{
|
||||
if (bIsSuccess == false)
|
||||
{
|
||||
m_pTransport->OnReceivedStatus(HTransport::T_FAILED_BEGIN);
|
||||
return;
|
||||
}
|
||||
|
||||
m_pTransport->OnReceivedStatus(HTransport::T_BEGIN_TRANSPORT);
|
||||
}
|
||||
|
||||
inline void OnReceive()
|
||||
{
|
||||
if (m_pTransport == NULL)
|
||||
return;
|
||||
|
||||
if (m_pTransport->OnPrepareReceive() == false)
|
||||
return;
|
||||
|
||||
int nReceivedSize = Receive(m_pReceiveBuffer, g_nSocketReceiveBlockSize);
|
||||
if (nReceivedSize <= 0)
|
||||
return;
|
||||
|
||||
if (m_pTransport->OnReceived(m_pReceiveBuffer, nReceivedSize) < 0)
|
||||
FinishTcp();
|
||||
}
|
||||
|
||||
inline int OnSendRetry()
|
||||
{
|
||||
return m_pTransport->OnSendRetry();
|
||||
}
|
||||
|
||||
inline void OnAccepted()
|
||||
{
|
||||
m_pTransport->OnReceivedStatus(HTransport::T_BEGIN_TRANSPORT);
|
||||
}
|
||||
|
||||
ON_TIMER(HMultiplexTransportTcpSocket, OnTimer) // add void OnTimer(DWORD nTimerID) {}
|
||||
|
||||
protected:
|
||||
char * m_pReceiveBuffer;
|
||||
bool m_bAutoDelete;
|
||||
DWORD m_nReconnectTime;
|
||||
|
||||
HMultiplexTransport * m_pTransport;
|
||||
};
|
||||
|
||||
inline void HMultiplexTransportTcpSocket::OnTimer(unsigned int nTimerId)
|
||||
{
|
||||
KillTimer(2181006);
|
||||
Create();
|
||||
Connect(0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
class HMultiplexTransportSslSocket : public HMultiplexSslSocket
|
||||
{
|
||||
public:
|
||||
HMultiplexTransportSslSocket()
|
||||
{
|
||||
m_bAutoDelete = false;
|
||||
m_nReconnectTime = 0;
|
||||
m_pTransport = NULL;
|
||||
}
|
||||
|
||||
HMultiplexTransportSslSocket(SOCKET sock, struct sockaddr_in * psaiRemote, HMpsDispatcher * pDispatcher)
|
||||
: HMultiplexSslSocket(sock, psaiRemote, pDispatcher)
|
||||
{
|
||||
m_bAutoDelete = false;
|
||||
m_nReconnectTime = 0;
|
||||
m_pTransport = NULL;
|
||||
}
|
||||
|
||||
~HMultiplexTransportSslSocket()
|
||||
{
|
||||
if (m_pTransport)
|
||||
delete m_pTransport;
|
||||
}
|
||||
|
||||
inline void AttachTransport(HMultiplexTransport * pTransport) { m_pTransport = pTransport; }
|
||||
inline HMultiplexTransport * GetTransport() { return m_pTransport; }
|
||||
|
||||
inline void SetAutoDelete(bool bAutoDelete) { m_bAutoDelete = bAutoDelete; }
|
||||
inline void SetAutoReconnect(DWORD nTime) { m_nReconnectTime = nTime; }
|
||||
|
||||
inline void OnAccepted()
|
||||
{
|
||||
HMultiplexSslSocket::OnAccepted();
|
||||
|
||||
m_pTransport->OnReceivedStatus(HTransport::T_BEGIN_TRANSPORT);
|
||||
}
|
||||
|
||||
protected:
|
||||
inline void OnClose()
|
||||
{
|
||||
if (m_bAutoDelete)
|
||||
SetState(MPS_DELETE); // auto delete
|
||||
else if (m_nReconnectTime > 0)
|
||||
SetTimer(2181006, m_nReconnectTime);
|
||||
|
||||
m_pTransport->OnReceivedStatus(HTransport::T_END_TRANSPORT);
|
||||
}
|
||||
|
||||
inline void OnReceive()
|
||||
{
|
||||
if (m_pTransport == NULL)
|
||||
return;
|
||||
|
||||
if (m_pTransport->OnPrepareReceive() == false)
|
||||
return;
|
||||
|
||||
Receive();
|
||||
|
||||
while (m_pStreamBufferForDecrypt->StoredSize() > 0)
|
||||
{
|
||||
//HLOGF(HLOG_WARNING, "SSL_TRACE, recv size = %d\n", m_pStreamBufferForDecrypt->StoredSize());
|
||||
//HLOGD(HLOG_WARNING, m_pStreamBufferForDecrypt->Head(), 40, true);
|
||||
|
||||
if (m_pStreamBufferForDecrypt->StoredSize() > (size_t)g_nSocketReceiveBlockSize)
|
||||
{
|
||||
if (m_pTransport->OnReceived(m_pStreamBufferForDecrypt->Head(), g_nSocketReceiveBlockSize) < 0)
|
||||
{
|
||||
FinishTcp();
|
||||
return;
|
||||
}
|
||||
m_pStreamBufferForDecrypt->Pop(g_nSocketReceiveBlockSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pTransport->OnReceived(m_pStreamBufferForDecrypt->Head(), m_pStreamBufferForDecrypt->StoredSize()) < 0)
|
||||
{
|
||||
FinishTcp();
|
||||
return;
|
||||
}
|
||||
m_pStreamBufferForDecrypt->Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline int OnSendRetry()
|
||||
{
|
||||
if (m_bEncryptRetry)
|
||||
return m_pTransport->OnSendRetry();
|
||||
|
||||
return SendBufferedData();
|
||||
}
|
||||
|
||||
inline void OnConnectChild(bool bIsSuccess)
|
||||
{
|
||||
if (bIsSuccess == false)
|
||||
{
|
||||
SetState(MPS_CLOSING);
|
||||
m_pTransport->OnReceivedStatus(HTransport::T_FAILED_BEGIN);
|
||||
return;
|
||||
}
|
||||
|
||||
m_pTransport->OnReceivedStatus(HTransport::T_BEGIN_TRANSPORT);
|
||||
}
|
||||
|
||||
ON_TIMER(HMultiplexTransportSslSocket, OnTimer) // add void OnTimer(DWORD nTimerID) {}
|
||||
|
||||
protected:
|
||||
bool m_bAutoDelete;
|
||||
DWORD m_nReconnectTime;
|
||||
|
||||
HMultiplexTransport * m_pTransport;
|
||||
};
|
||||
|
||||
inline void HMultiplexTransportSslSocket::OnTimer(unsigned int nTimerId)
|
||||
{
|
||||
KillTimer(2181006);
|
||||
Create();
|
||||
Connect(0);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
inline bool HMultiplexTransport::GetTransportInfo(const char * pName, void * pValue)
|
||||
{
|
||||
if (strcmp(pName, "peer_ip") == 0)
|
||||
{
|
||||
int nResult = m_pMulplexTransportSocket->GetPeerAddress((char *)pValue, NULL);
|
||||
if (nResult)
|
||||
{
|
||||
HLOGF(HLOG_WARNING, "[WARN], MplxTrnsp, Failed to GetPeerAddress 1, error = %d\n", nResult);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(pName, "peer_port") == 0)
|
||||
{
|
||||
int nResult = m_pMulplexTransportSocket->GetPeerAddress(NULL, (u_short *)pValue);
|
||||
if (nResult)
|
||||
{
|
||||
HLOGF(HLOG_WARNING, "[WARN], MplxTrnsp, Failed to GetPeerAddress 2, error = %d\n", nResult);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(pName, "peer_address") == 0)
|
||||
{
|
||||
char szIp[32];
|
||||
u_short nPort = 0;
|
||||
int nResult = m_pMulplexTransportSocket->GetPeerAddress(szIp, &nPort);
|
||||
if (nResult)
|
||||
{
|
||||
HLOGF(HLOG_WARNING, "[WARN], MplxTrnsp, Failed to GetPeerAddress 3, error = %d\n", nResult);
|
||||
return false;
|
||||
}
|
||||
sprintf((char *)pValue, "%s:%d", szIp, nPort);
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(pName, "is_ssl_socket") == 0)
|
||||
{
|
||||
*((bool *)pValue) = m_pMulplexTransportSocket->IsSslSocket();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void HMultiplexTransport::Terminate()
|
||||
{
|
||||
m_pMulplexTransportSocket->FinishTcp();
|
||||
}
|
||||
|
||||
inline int HMultiplexTransport::Send(const char * pData, int nSize)
|
||||
{
|
||||
return m_pMulplexTransportSocket->Send(pData, nSize);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
template<class _THandler, class _TSocket>
|
||||
class HMulplexTransportListenSocket : public HMultiplexListenSocket
|
||||
{
|
||||
public:
|
||||
HMulplexTransportListenSocket() {}
|
||||
~HMulplexTransportListenSocket() {}
|
||||
|
||||
protected:
|
||||
HMultiplexTcpSocket * OnAccept(SOCKET sock, struct sockaddr_in * psaiRemote)
|
||||
{
|
||||
HMultiplexTransport * pMultiplexTransport = new HMultiplexTransport;
|
||||
pMultiplexTransport->AttachHandler(new _THandler);
|
||||
|
||||
_TSocket * pSocket = new _TSocket(sock, psaiRemote, GetDispatcher());
|
||||
pMultiplexTransport->SetMpSocket(pSocket);
|
||||
|
||||
pSocket->AttachTransport(pMultiplexTransport);
|
||||
pSocket->SetAutoDelete(true);
|
||||
|
||||
return pSocket;
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
class HMulplexSocketConnector
|
||||
{
|
||||
public:
|
||||
HMulplexSocketConnector() { m_pVecOutboundIp = NULL; m_nOutboundIpIndex = -1; }
|
||||
virtual ~HMulplexSocketConnector() {}
|
||||
|
||||
inline void SetOutboundIpList(HStrVector * pVector) { m_pVecOutboundIp = pVector; }
|
||||
inline void SetOutboundIpIndex(int nIndex) { m_nOutboundIpIndex = nIndex; }
|
||||
|
||||
virtual bool Connect(const char * pszAddress, u_short nPort, unsigned nTimeout, HMpsDispatcher * pDispatcher) { return false; }
|
||||
|
||||
protected:
|
||||
HStrVector * m_pVecOutboundIp;
|
||||
int m_nOutboundIpIndex;
|
||||
};
|
||||
|
||||
template<class _THandler, class _TSocket>
|
||||
class HMulplexTransportConnector : public HMulplexSocketConnector
|
||||
{
|
||||
public:
|
||||
HMulplexTransportConnector() { m_pHandler = NULL; }
|
||||
~HMulplexTransportConnector() {}
|
||||
|
||||
inline _THandler * GetHandler() { return m_pHandler; }
|
||||
|
||||
inline bool Connect(const char * pszAddress, u_short nPort, unsigned nTimeout, HMpsDispatcher * pDispatcher, unsigned long nAutoReconnectTime = 0)
|
||||
{
|
||||
HMultiplexTransport * pMultiplexTransport = new HMultiplexTransport;
|
||||
|
||||
m_pHandler = new _THandler;
|
||||
pMultiplexTransport->AttachHandler(m_pHandler);
|
||||
|
||||
_TSocket * pSocket = new _TSocket;
|
||||
if (pSocket->Create() == false)
|
||||
{
|
||||
delete pSocket;
|
||||
delete pMultiplexTransport;
|
||||
return false;
|
||||
}
|
||||
pMultiplexTransport->SetMpSocket(pSocket);
|
||||
pSocket->AttachTransport(pMultiplexTransport);
|
||||
|
||||
if (nAutoReconnectTime > 0)
|
||||
pSocket->SetAutoReconnect(nAutoReconnectTime);
|
||||
else
|
||||
pSocket->SetAutoDelete(true);
|
||||
|
||||
HLOGF(HLOG_INFO3, "INFO, MpConnector, Connect, inst = 0x%x, %s:%d\n", this, pszAddress, nPort);
|
||||
|
||||
if (IsIpString(pszAddress))
|
||||
pSocket->SetRemoteAddress(pszAddress, nPort);
|
||||
else
|
||||
pSocket->SetRemoteAddressHostByName(pszAddress, nPort);
|
||||
|
||||
if (m_pVecOutboundIp && m_pVecOutboundIp->size() > 0)
|
||||
{
|
||||
// outbound load balance
|
||||
static int nIpCount = m_pVecOutboundIp->size();
|
||||
static int nIpIndex = 0;
|
||||
static u_short nPort = 20000;
|
||||
|
||||
if (nIpCount <= 0)
|
||||
return false;
|
||||
|
||||
if (++nIpIndex >= nIpCount)
|
||||
nIpIndex = 0;
|
||||
|
||||
for (int i = 20000; i < 60000; i++)
|
||||
{
|
||||
if (++nPort >= 60000)
|
||||
nPort = 20000;
|
||||
|
||||
if (m_nOutboundIpIndex != -1)
|
||||
{
|
||||
if (pSocket->Bind((*m_pVecOutboundIp)[m_nOutboundIpIndex], nPort))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pSocket->Bind((*m_pVecOutboundIp)[nIpIndex], nPort))
|
||||
break;
|
||||
}
|
||||
|
||||
Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
if (pSocket->Connect(nTimeout) == false)
|
||||
{
|
||||
delete pSocket;
|
||||
return false;
|
||||
}
|
||||
|
||||
pDispatcher->Attach(pSocket);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
_THandler * m_pHandler;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
template<class _THandler, class _TSocket>
|
||||
class HMulplexTransportListenThread : public HMultiplexListenThread<HMultiplexTcpSocket>
|
||||
{
|
||||
public:
|
||||
HMulplexTransportListenThread() {}
|
||||
~HMulplexTransportListenThread() {}
|
||||
|
||||
protected:
|
||||
HMultiplexTcpSocket * OnAccept(SOCKET sock, struct sockaddr_in * psaiRemote)
|
||||
{
|
||||
HMultiplexTransport * pMultiplexTransport = new HMultiplexTransport;
|
||||
pMultiplexTransport->AttachHandler(new _THandler);
|
||||
#if 1
|
||||
HMpsDispatcher * pDispatcher = m_pListDispatcher->GetLazyDispatcher();
|
||||
_TSocket * pSocket = new _TSocket(sock, psaiRemote, pDispatcher);
|
||||
pMultiplexTransport->SetMpSocket(pSocket);
|
||||
|
||||
pSocket->AttachTransport(pMultiplexTransport);
|
||||
pSocket->SetAutoDelete(true);
|
||||
|
||||
pDispatcher->AttachWithLock(pSocket);
|
||||
return pSocket;
|
||||
#else
|
||||
HMpsDispatcherList::iterator iter;
|
||||
int i = 0;
|
||||
for (iter = m_pListDispatcher->begin(); iter != m_pListDispatcher->end(); iter++)
|
||||
{
|
||||
if ((*iter)->IsProcessing() == false)
|
||||
i++;
|
||||
}
|
||||
//HLOGF(HLOG_WARNING, "[TRACE], MplxTrnspLstnThr_0x%x, lazy dispatcher count = %d\n", this, i);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (iter = m_pListDispatcher->begin(); iter != m_pListDispatcher->end(); iter++)
|
||||
{
|
||||
if ((*iter)->IsProcessing() == false)
|
||||
{
|
||||
_TSocket * pSocket = new _TSocket(sock, psaiRemote, *iter);
|
||||
pMultiplexTransport->SetMpSocket(pSocket);
|
||||
|
||||
pSocket->AttachTransport(pMultiplexTransport);
|
||||
pSocket->SetAutoDelete(true);
|
||||
|
||||
(*iter)->AttachWithLock(pSocket);
|
||||
return pSocket;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#if 1
|
||||
typedef std::list<HMultiplexListenThread<HMultiplexTcpSocket> *> HMultiplexListenThreadList;
|
||||
#else
|
||||
class HMultiplexListenThreadList : public std::list<HMultiplexListenThread<HMultiplexTcpSocket> *>
|
||||
{
|
||||
public:
|
||||
HMultiplexListenThreadList() {}
|
||||
~HMultiplexListenThreadList() {}
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // MULTIPLEX_TRANSPORT__H_
|
||||
Reference in New Issue
Block a user