1
0

cSocketThreads plugged in for cClientHandle reading. Sending still kept the old way. Please help me test this commit thoroughly, this is a change that can break on subtleties.

git-svn-id: http://mc-server.googlecode.com/svn/trunk@244 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com
2012-02-08 10:02:46 +00:00
parent dcd82b6988
commit c82c636d8c
8 changed files with 267 additions and 233 deletions

View File

@@ -91,7 +91,6 @@ extern std::string GetWSAError();
cClientHandle::cClientHandle(const cSocket & a_Socket)
: m_ProtocolVersion(23)
, m_pReceiveThread(NULL)
, m_pSendThread(NULL)
, m_Socket(a_Socket)
, m_Semaphore(MAX_SEMAPHORES)
@@ -105,8 +104,6 @@ cClientHandle::cClientHandle(const cSocket & a_Socket)
, m_Ping(1000)
, m_bPositionConfirmed(false)
{
LOG("cClientHandle::cClientHandle");
cTimer t1;
m_LastPingTime = t1.GetNowTime();
@@ -143,13 +140,11 @@ cClientHandle::cClientHandle(const cSocket & a_Socket)
memset(m_LoadedChunks, 0x00, sizeof(m_LoadedChunks));
//////////////////////////////////////////////////////////////////////////
m_pReceiveThread = new cThread(ReceiveThread, this, "cClientHandle::ReceiveThread");
m_pSendThread = new cThread(SendThread, this, "cClientHandle::SendThread");
m_pReceiveThread->Start(true);
m_pSendThread->Start (true);
//////////////////////////////////////////////////////////////////////////
LOG("New ClientHandle");
LOG("New ClientHandle created at %p", this);
}
@@ -158,7 +153,7 @@ cClientHandle::cClientHandle(const cSocket & a_Socket)
cClientHandle::~cClientHandle()
{
LOG("Deleting client %s", GetUsername().c_str());
LOG("Deleting client \"%s\"", GetUsername().c_str());
for(unsigned int i = 0; i < VIEWDISTANCE*VIEWDISTANCE; i++)
{
@@ -185,7 +180,6 @@ cClientHandle::~cClientHandle()
// First stop sending thread
m_bKeepThreadGoing = false;
cCSLock Lock(m_SocketCriticalSection);
if (m_Socket.IsValid())
{
cPacket_Disconnect Disconnect;
@@ -193,17 +187,10 @@ cClientHandle::~cClientHandle()
m_Socket.Send(&Disconnect);
m_Socket.CloseSocket();
}
Lock.Unlock();
m_Semaphore.Signal();
delete m_pReceiveThread;
delete m_pSendThread;
while (!m_PendingParsePackets.empty())
{
delete *m_PendingParsePackets.begin();
m_PendingParsePackets.erase(m_PendingParsePackets.begin());
}
while (!m_PendingNrmSendPackets.empty())
{
delete *m_PendingNrmSendPackets.begin();
@@ -224,6 +211,8 @@ cClientHandle::~cClientHandle()
{
delete m_PacketMap[i];
}
LOG("ClientHandle at %p destroyed", this);
}
@@ -233,11 +222,13 @@ cClientHandle::~cClientHandle()
void cClientHandle::Destroy()
{
m_bDestroyed = true;
cCSLock Lock(m_SocketCriticalSection);
if (m_Socket.IsValid())
{
m_Socket.CloseSocket();
}
// Synchronize with the cSocketThreads (so that they don't call us anymore)
cRoot::Get()->GetServer()->ClientDestroying(this);
}
@@ -419,31 +410,6 @@ void cClientHandle::RemoveFromAllChunks()
void cClientHandle::AddPacket(cPacket * a_Packet)
{
cCSLock Lock(m_CriticalSection);
m_PendingParsePackets.push_back(a_Packet->Clone());
}
void cClientHandle::HandlePendingPackets()
{
cCSLock Lock(m_CriticalSection);
for (PacketList::iterator itr = m_PendingParsePackets.begin(); itr != m_PendingParsePackets.end(); ++itr)
{
HandlePacket(*itr);
delete *itr;
}
m_PendingParsePackets.clear();
}
void cClientHandle::HandlePacket(cPacket * a_Packet)
{
m_TimeLastPacket = cWorld::GetTime();
@@ -1766,14 +1732,11 @@ void cClientHandle::SendThread(void *lpParam)
}
Lock.Unlock();
cCSLock SocketLock(self->m_SocketCriticalSection);
if (!self->m_Socket.IsValid())
{
break;
}
bool bSuccess = self->m_Socket.Send(Packet);
SocketLock.Unlock();
if (!bSuccess)
{
@@ -1799,84 +1762,6 @@ void cClientHandle::SendThread(void *lpParam)
void cClientHandle::ReceiveThread(void *lpParam)
{
LOG("ReceiveThread");
cClientHandle* self = (cClientHandle*)lpParam;
char temp = 0;
int iStat = 0;
cSocket socket = self->GetSocket();
AString Received;
while (self->m_bKeepThreadGoing)
{
char Buffer[1024];
iStat = socket.Receive(Buffer, sizeof(Buffer), 0);
if (cSocket::IsSocketError(iStat) || (iStat == 0))
{
LOG("CLIENT DISCONNECTED (%i bytes):%s", iStat, cSocket::GetLastErrorString().c_str());
break;
}
Received.append(Buffer, iStat);
// Parse all complete packets in Received:
while (!Received.empty())
{
cPacket* pPacket = self->m_PacketMap[(unsigned char)Received[0]];
if (pPacket)
{
int NumBytes = pPacket->Parse(Received.data() + 1, Received.size() - 1);
if (NumBytes == PACKET_ERROR)
{
LOGERROR("Protocol error while parsing packet type 0x%x; disconnecting client \"%s\"", Received[0], self->m_Username.c_str());
cPacket_Disconnect DC("Protocol error");
socket.Send(&DC);
cSleep::MilliSleep(1000); // Give packet some time to be received
return;
}
else if (NumBytes == PACKET_INCOMPLETE)
{
// Not a complete packet
break;
}
else
{
// Packet parsed successfully, add it to internal queue:
self->AddPacket(pPacket);
// Erase the packet from the buffer:
assert(Received.size() > (size_t)NumBytes);
Received.erase(0, NumBytes + 1);
}
}
else
{
LOGERROR("Unknown packet type: 0x%2x", Received[0]);
AString Reason;
Printf(Reason, "[C->S] Unknown PacketID: 0x%02x", Received[0]);
cPacket_Disconnect DC(Reason);
socket.Send(&DC);
cSleep::MilliSleep(1000); // Give packet some time to be received
break;
}
} // while (!Received.empty())
} // while (self->m_bKeepThreadGoing)
self->Destroy();
LOG("ReceiveThread STOPPED");
return;
}
const AString & cClientHandle::GetUsername(void) const
{
return m_Username;
@@ -1886,9 +1771,79 @@ const AString & cClientHandle::GetUsername(void) const
const cSocket & cClientHandle::GetSocket()
void cClientHandle::DataReceived(const char * a_Data, int a_Size)
{
return m_Socket;
// Data is received from the client
m_ReceivedData.append(a_Data, a_Size);
// Parse and handle all complete packets in m_ReceivedData:
while (!m_ReceivedData.empty())
{
cPacket* pPacket = m_PacketMap[(unsigned char)m_ReceivedData[0]];
if (pPacket == NULL)
{
LOGERROR("Unknown packet type 0x%02x from client \"%s\"", (unsigned char)m_ReceivedData[0], m_Username.c_str());
AString Reason;
Printf(Reason, "[C->S] Unknown PacketID: 0x%02x", m_ReceivedData[0]);
cPacket_Disconnect DC(Reason);
m_Socket.Send(&DC);
cSleep::MilliSleep(1000); // Give packet some time to be received
Destroy();
return;
}
int NumBytes = pPacket->Parse(m_ReceivedData.data() + 1, m_ReceivedData.size() - 1);
if (NumBytes == PACKET_ERROR)
{
LOGERROR("Protocol error while parsing packet type 0x%02x; disconnecting client \"%s\"", (unsigned char)m_ReceivedData[0], m_Username.c_str());
cPacket_Disconnect DC("Protocol error");
m_Socket.Send(&DC);
cSleep::MilliSleep(1000); // Give packet some time to be received
Destroy();
return;
}
else if (NumBytes == PACKET_INCOMPLETE)
{
// Not a complete packet
break;
}
else
{
// Packet parsed successfully, add it to internal queue:
HandlePacket(pPacket);
// Erase the packet from the buffer:
assert(m_ReceivedData.size() > (size_t)NumBytes);
m_ReceivedData.erase(0, NumBytes + 1);
}
} // while (!Received.empty())
}
void cClientHandle::GetOutgoingData(AString & a_Data)
{
// Data can be sent to client
// TODO
}
void cClientHandle::SocketClosed(void)
{
// The socket has been closed for any reason
// TODO
/*
self->Destroy();
LOG("Client \"%s\" disconnected", GetLogName().c_str());
*/
}