📄 netgateway.cc
字号:
/*///////////////////////////////////////////////////////////////////////////
UDP连接封装管理
李亦
2006.6.15
/*///////////////////////////////////////////////////////////////////////////
#include "platform/platform.h"
#include "platform/event.h"
#include "sim/netConnection.h"
#include "server/net/netGateway.h"
#include "core/bitStream.h"
#include "math/mRandom.h"
#include "platform/gameInterface.h"
#include "server/net/AuthSocket.h"
#include "server/net/AuthSocket.h"
//NetGateway *GNet = NULL;
namespace CS
{
NetGateway::NetGateway()
{
m_pSocketMain = NULL;
//m_pSocketNew = NULL;
//AssertFatal(GNet == NULL, "ERROR: Multiple net interfaces declared.");
//GNet = this;
//m_pNetManager = pManager;
//mLastTimeoutCheckTime = 0;
//mAllowConnections = true;
}
BOOL NetGateway::ClientBlockSequene()
{
CltStartConnection(); // CltSendChallengeRequest
//PT_CHALLENGE_REQUEST
m_pSocketMain->BlockRecvPacket(PT_CHALLENGE_RESPONSE);
//CltHandleChallengeResponse
//CltSendConnectRequest
//PT_CONNECT_REQUEST
m_pSocketMain->BlockRecvPacket(PT_CONNECT_RESPONSE);
return TRUE;
}
BOOL NetGateway::ServerBlockSequene()
{
SvrAcceptConnection();
m_pSocketMain->BlockRecvPacket(PT_CHALLENGE_REQUEST);
//SvrHandleChallengeRequest
//PT_CHALLENGE_RESPONSE
m_pSocketMain->BlockRecvPacket(PT_CONNECT_REQUEST);
//SvrHandleConnectRequest
//SvrSendConnectResponse
//PT_CONNECT_RESPONSE
return TRUE;
}
BOOL NetGateway::ProcessRecvPackets(BitStream *stream,U8 uPacketType)
{
AssertFatal(m_pSocketMain,"需要关联AuthSocket对象");
//NetConnection *conn = m_pSocketMain->GetConnection();
//AssertFatal(conn,"需要AuthSocket对象需要关联Connection对象");
NetAddress *addr = (NetAddress *)m_pSocketMain->GetNetAddress();
switch(uPacketType)
{
case PT_CHALLENGE_REQUEST:
SvrHandleChallengeRequest(addr, stream);
break;
case PT_CHALLENGE_RESPONSE:
CltHandleChallengeResponse(addr, stream);
break;
case PT_CONNECT_REQUEST:
SvrHandleConnectRequest(addr, stream);
break;
case PT_CONNECT_RESPONSE:
CltHandleConnectResponse(addr, stream);
break;
//case PT_CONNECT_REJECT:
// CltHandleConnectReject(addr, stream);
// break;
case PT_DISCONNECT:
CltHandleDisconnect(addr, stream);
break;
default:
return HandleInfoPacket(addr, uPacketType, stream);
break;
}//switch
return TRUE;
}
//Client
void NetGateway::CltSendChallengeRequest(/*NetConnection *conn*/)
{
AssertFatal(m_pSocketMain,"需要关联AuthSocket对象");
NetConnection *conn = m_pSocketMain->GetConnection();
AssertFatal(conn,"需要AuthSocket对象需要关联Connection对象");
//Con::printf("Sending Connect challenge Request");
BitStream out(0,0);
if(m_pSocketMain->BeginSend(&out,FALSE,PT_CHALLENGE_REQUEST))
{
//数据
out.write(conn->getSequence());
conn->mConnectSendCount++;
conn->mConnectLastSendTime = Platform::getVirtualMilliseconds();
m_pSocketMain->EndSend(&out,TRUE);
}
}
//Server
void NetGateway::SvrHandleChallengeRequest(const NetAddress *addr, BitStream *stream)
{
//NetAddress *addr = (NetAddress *)m_pSocketMain->GetNetAddress();
//BitStream *stream = m_pSocketMain->BeginRecv(0,FALSE);
char buf[256];
Net::addressToString(addr, buf);
Con::printf("Got Connect challenge Request from %s", buf);
if(!mAllowConnections)
return;
U32 connectSequence;
U32 addressDigest[4];
//数据读
stream->read(&connectSequence);
if(!mRandomDataInitialized)
InitRandomData();
computeNetMD5(addr, connectSequence, addressDigest);
BitStream out(0,0);
if(m_pSocketMain->BeginSend(&out,FALSE,PT_CHALLENGE_RESPONSE))
{
//数据写
out.write(connectSequence);
out.write(addressDigest[0]);
out.write(addressDigest[1]);
out.write(addressDigest[2]);
out.write(addressDigest[3]);
m_pSocketMain->EndSend(&out,TRUE);
}
}
//-----------------------------------------------------------------------------
//Client
void NetGateway::CltHandleChallengeResponse(const NetAddress *address, BitStream *stream)
{
Con::printf("Got Connect challenge Response");
U32 connectSequence;
//数据
stream->read(&connectSequence);
NetConnection *conn = m_pSocketMain->GetConnection();// findPendingConnection(address, connectSequence);
if(!conn || conn->getConnectionState() != NetConnection::AwaitingChallengeResponse)
return;
U32 addressDigest[4];
//数据
stream->read(&addressDigest[0]);
stream->read(&addressDigest[1]);
stream->read(&addressDigest[2]);
stream->read(&addressDigest[3]);
conn->setAddressDigest(addressDigest);
conn->setConnectionState(NetConnection::AwaitingConnectResponse);
conn->mConnectSendCount = 0;
Con::printf("Sending Connect Request");
CltSendConnectRequest(/*conn*/);
}
//-----------------------------------------------------------------------------
//Client
void NetGateway::CltSendConnectRequest(/*NetConnection *conn*/)
{
AssertFatal(m_pSocketMain,"需要关联AuthSocket对象");
NetConnection *conn = m_pSocketMain->GetConnection();
AssertFatal(conn,"需要AuthSocket对象需要关联Connection对象");
BitStream out(0,0);
if(m_pSocketMain->BeginSend(&out,FALSE,PT_CONNECT_REQUEST))
{
U32 addressDigest[4];
conn->getAddressDigest(addressDigest);
//识别码
//out.write(U8(PT_CONNECT_REQUEST));
//数据
out.write(conn->getSequence());
out.write(addressDigest[0]);
out.write(addressDigest[1]);
out.write(addressDigest[2]);
out.write(addressDigest[3]);
////////////////////////////////////////////////
//传递connection的类名、连接参数...
out.writeString(conn->getClassName());
conn->writeConnectRequest(&out);
conn->mConnectSendCount++;
conn->mConnectLastSendTime = Platform::getVirtualMilliseconds();
m_pSocketMain->EndSend(&out, TRUE);
}
}
//-----------------------------------------------------------------------------
void NetGateway::SvrHandleConnectRequest(const NetAddress *address, BitStream *stream)
{
if(!mAllowConnections)
return;
Con::printf("Got Connect Request");
U32 connectSequence;
//数据
stream->read(&connectSequence);
// see if the connection is in the main connection table:
NetConnection *connect = m_pSocketMain->GetConnection();//NetConnection::lookup(address);
if(connect && connect->getSequence() == connectSequence)
{
SvrSendConnectResponse(TRUE);
return;
}
U32 addressDigest[4];
U32 computedAddressDigest[4];
//数据
stream->read(&addressDigest[0]);
stream->read(&addressDigest[1]);
stream->read(&addressDigest[2]);
stream->read(&addressDigest[3]);
computeNetMD5(address, connectSequence, computedAddressDigest);
if(addressDigest[0] != computedAddressDigest[0] ||
addressDigest[1] != computedAddressDigest[1] ||
addressDigest[2] != computedAddressDigest[2] ||
addressDigest[3] != computedAddressDigest[3])
return; // bogus connection attempt
if(connect)
{
if(connect->getSequence() > connectSequence)
return; // the existing connection should be kept - the incoming request is stale.
else
connect->deleteObject(); // disconnect this one, and allow the new one to be created.
}
///////////////////////////////////////////////////
//传递connection的类名、连接参数...
char connectionClass[255];
//数据
stream->readString(connectionClass);
ConsoleObject *co = ConsoleObject::create(connectionClass);
NetConnection *conn = dynamic_cast<NetConnection *>(co);
if(!conn || !conn->canRemoteCreate())
{
delete co;
return;
}
conn->registerObject();
conn->setNetAddress(address);
conn->setNetworkConnection(true);
conn->setSequence(connectSequence);
const char *errorString = NULL;
//数据流,连接拒绝处理
if(!conn->readConnectRequest(stream, &errorString))
{
SvrSendConnectResponse(FALSE,errorString);
conn->deleteObject();
return;
}
//关联连接
conn->setNetworkConnection(true);
conn->onConnectionEstablished(false);
conn->setEstablished();
conn->setConnectSequence(connectSequence);
//m_pSocketNew->AttachConnection(conn);
//m_pSocketNew->SetESTABLISHED();
conn->attachSocket(m_pSocketMain);
SvrSendConnectResponse(TRUE);
}
//-----------------------------------------------------------------------------
void NetGateway::SvrSendConnectResponse(BOOL bAccept,CSTR szReason)
{
AssertFatal(m_pSocketMain,"需要关联AuthSocket对象");
NetConnection *conn = m_pSocketMain->GetConnection();
AssertFatal(conn,"需要AuthSocket对象需要关联Connection对象");
BitStream out(0,0);
if(m_pSocketMain->BeginSend(&out,FALSE,PT_CONNECT_RESPONSE))
{
//数据
out.write(conn->getSequence());
//数据接受响应处理
if(out.writeFlag(bool(bAccept))) //Accept标志
{
conn->writeConnectAccept(&out);
}
else //Reject标志
{
if(szReason && szReason[0])
out.writeString(szReason);
}
m_pSocketMain->EndSend(&out, TRUE);
}
}
//Client
void NetGateway::CltHandleConnectResponse(const NetAddress *address, BitStream *stream)
{
U32 connectSequence;
//数据
stream->read(&connectSequence);
NetConnection *conn = m_pSocketMain->GetConnection();//findPendingConnection(address, connectSequence);
if(!conn || conn->getConnectionState() != NetConnection::AwaitingConnectResponse)
return;
////////////////////////////////////////
//Reject处理
if(!stream->readFlag())
{
char reason[256];
//数据
stream->readString(reason);
conn->onConnectionRejected(reason);
conn->deleteObject();
return;
}
/////////////////////////////////////////
//Accept处理
const char *errorString = NULL;
//数据接受响应处理
if(!conn->readConnectAccept(stream, &errorString))
{
conn->handleStartupError(errorString);
//removePendingConnection(conn);
conn->deleteObject();
return;
}
conn->setNetAddress(address);
//removePendingConnection(conn); // remove from the pending connection list
conn->setNetworkConnection(true);
conn->onConnectionEstablished(true); // notify the connection that it has been established
conn->setEstablished(); // installs the connection in the connection table, and causes pings/timeouts to happen
conn->setConnectSequence(connectSequence);
//m_pSocketMain->SetESTABLISHED();
}
//Server
void NetGateway::SvrSendDisconnectPacket(/*NetConnection *conn,*/ const char *reason)
{
Con::printf("Issuing Disconnect packet.");
AssertFatal(m_pSocketMain,"需要关联AuthSocket对象");
NetConnection *conn = m_pSocketMain->GetConnection();
AssertFatal(conn,"需要AuthSocket对象需要关联Connection对象");
BitStream out(0,0);
if(m_pSocketMain->BeginSend(&out,FALSE,PT_DISCONNECT))
{
// send a disconnect packet...
U32 connectSequence = conn->getSequence();
//识别码
//out.write(U8(PT_DISCONNECT));
//数据
out.write(connectSequence);
out.writeString(reason);
m_pSocketMain->EndSend(&out, TRUE);
}
}
//Client
void NetGateway::CltHandleDisconnect(const NetAddress *address, BitStream *stream)
{
NetConnection *conn = m_pSocketMain->GetConnection();//NetConnection::lookup(address);
if(!conn)
return;
U32 connectSequence;
char reason[256];
//数据
stream->read(&connectSequence);
stream->readString(reason);
if(conn->getSequence() != connectSequence)
return;
conn->onDisconnect(reason);
conn->deleteObject();
}
BOOL NetGateway::HandleInfoPacket(const NetAddress *address, U8 uPacketType, BitStream *stream)
{
return FALSE;
}
void NetGateway::SvrAcceptConnection(/*CAuthSocket *pSocketNew*/)
{
//m_pSocketNew = pSocketNew;
}
void NetGateway::SvrListenConnection(CAuthSocket *pSocket)
{
m_pSocketMain = pSocket;
}
void NetGateway::CltStartConnection()
{
//addPendingConnection(conn);
AssertFatal(m_pSocketMain,"需要关联AuthSocket对象");
NetConnection *conn = m_pSocketMain->GetConnection();
AssertFatal(conn,"需要AuthSocket对象需要关联Connection对象");
conn->mConnectionSendCount = 0;
conn->setConnectSequence(Platform::getVirtualMilliseconds());
conn->setConnectionState(NetConnection::AwaitingChallengeResponse);
// This is a the client side of the connection, so set the connection to
// server flag. We need to set this early so that if the connection times
// out, its onRemove() will handle the cleanup properly.
conn->setIsConnectionToServer();
// Everything set, so send off the request.
CltSendChallengeRequest(/*conn*/);
}
void NetGateway::CheckTimeouts()
{
Parent::CheckTimeouts();
// U32 time = Platform::getVirtualMilliseconds();
// if(time < mLastTimeoutCheckTime + TimeoutCheckInterval)
// return;
//for(U32 i = 0; i < mPendingConnections.size();)
//{
// NetConnection *pending = mPendingConnections[i];
// if(pending->getConnectionState() == NetConnection::AwaitingChallengeResponse &&
// time > pending->mConnectLastSendTime + ChallengeRetryTime)
// {
// if(pending->mConnectSendCount > ChallengeRetryCount)
// {
// pending->onConnectTimedOut();
// removePendingConnection(pending);
// pending->deleteObject();
// continue;
// }
// else
// CltSendChallengeRequest(pending);
// }
// else if(pending->getConnectionState() == NetConnection::AwaitingConnectResponse &&
// time > pending->mConnectLastSendTime + ConnectRetryTime)
// {
// if(pending->mConnectSendCount > ConnectRetryCount)
// {
// pending->onConnectTimedOut();
// removePendingConnection(pending);
// pending->deleteObject();
// continue;
// }
// else
// CltSendConnectRequest(pending);
// }
// i++;
//}
}
};//namespace RPGServer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -