Hello, I've tried multiple forums and still cannot get a response from anyone, so I was hoping you guys would be able to help. I know this belongs in Networking but I chose this forum because it is the most actively viewed and I need a solution to this problem pronto!

In my Battle.net bot I am attempting to use overlapped I/O (not I/O completion ports). However, I am running into a very annoying runtime error which I have never really been able to resolve, and AFAIK it occurs randomly, though more frequently under high stress conditions (such as several chat events and server traffic).

The problem is that the buffer is overflowing causing potential errors, and often times leads to the bot disconnecting (not crashing). So in this post I've included the key parts to my networking/buffering code. If you need more information, I'd be happy to post it, just tell me what you need.


This is the Connection class (Header/Source file inclusive):
Code:
#include "Includes.h"
#include "BufferWriter.h"

#ifndef CONNECTION_H
#define CONNECTION_H

const unsigned long BUFFER_SIZE = 1024;

class Connection {

public:

	explicit __stdcall Connection(void) : _port(0), _buflen(0), _bufstart(0), _socket((unsigned int)-1), _socketEvent(0), _bytes(0), _flags(0), _sentPackets(0), _recvPackets(0)
	{
		_server = new char[50];

		ZeroMemory(_server, sizeof(_server));

		memset(&_sendOv, 0, sizeof(_sendOv));
		memset(&_recvOv, 0, sizeof(_recvOv));
		memset(&_WSASendBuf, 0, sizeof(_WSASendBuf));
		memset(&_WSARecvBuf, 0, sizeof(_WSARecvBuf));
	}

	virtual __stdcall ~Connection(void)
	{
		delete [] _server;
	}


	// non-generic class function; may remove or use with PacketWriter.h and its derived classes
	void __stdcall SendPacket(BufferWriter* message);

	// pure virtual functions; override these functions in your derived connection classes
	virtual bool __stdcall DoEvents() = 0; // processes network events on the socket event
	virtual void __stdcall ProcessData(char* buffer) = 0; // processes the data into a message format then iterates to the next message if necessary
	virtual void __stdcall ProcessMessages(unsigned char packetID, char* data, unsigned short len) = 0; // receives the message and processes it accordingly

	bool __stdcall ConnectSocket(); // connects the socket to the server specified
	bool __stdcall DisconnectSocket(); // disconnects the socket from the server specified

	// overlapped receive completion routine
	__inline static void CALLBACK StaticRecvComplete(unsigned long dwError, unsigned long dwTransferred, LPWSAOVERLAPPED lpOverlapped, unsigned long flags)
	{
		reinterpret_cast<Connection *>(lpOverlapped->hEvent)->RecvComplete(dwError, dwTransferred, lpOverlapped, flags);
	}

	// overlapped send completion routine
	__inline static void CALLBACK StaticSendComplete(unsigned long dwError, unsigned long dwTransferred, LPWSAOVERLAPPED lpOverlapped, unsigned long flags)
	{
		reinterpret_cast<Connection *>(lpOverlapped->hEvent)->SendComplete(dwError, dwTransferred, lpOverlapped, flags);
	}

	void __stdcall RecvComplete(unsigned long dwError, unsigned long dwTransferred, LPWSAOVERLAPPED lpOverlapped, unsigned long flags);
// handles the completion routine data; called by static receive completion routine
	void __stdcall SendComplete(unsigned long dwError, unsigned long dwTransferred, LPWSAOVERLAPPED lpOverlapped, unsigned long flags);
// handles the completion routine data; called by static send completion routine
	 
	void __stdcall SendMessage(char* message);
// sends the buffered message to the server; you may want to make this pure virtual and implement your own method in the base class or create a new function with a new argument list for sending messages
	
	
	__inline char* GetServer(void)
	{
		return _server;
	}

	__inline unsigned short GetPort(void)
	{
		return _port;
	}

	__inline HANDLE GetSocketEvent(void)
	{
		return _socketEvent;
	}

	unsigned long _sentPackets;
	unsigned long _recvPackets;

protected:

	char* _server; // pointer to the address of the server
	unsigned short _port; // the port the server listens on

	unsigned long _buflen; // the length of the buffer when receiving data
	unsigned long _bufstart; // the buffer start position to read and store data

	SOCKET _socket; // the socket that will be connected to the server
	HANDLE _socketEvent; // the socket event used in a wait function

	char _recvBuffer[BUFFER_SIZE]; // the buffer in which data is stored for receiving
	char _sendBuffer[BUFFER_SIZE]; // the buffer in which data is stored for sending

	OVERLAPPED _sendOv; // the overlapped struct used for sending routines
	OVERLAPPED _recvOv; // the overlapped struct used for receiving routines

	WSABUF _WSARecvBuf; // the standard WSA buffer used in WSARecv
	WSABUF _WSASendBuf; // the standard WSA buffer used in WSASend

	unsigned long _bytes; // argument passed to WSARecv & WSASend (not used)
	unsigned long _flags; // argument passed to WSARecv & WSASend (not used)
};

#endif


#include "Includes.h"
#include "Connection.h"
#include "BufferWriter.h"
#include "GlobalData.h"
#include "Functions.h"

bool __stdcall Connection::ConnectSocket()
{
	struct hostent *host_entry;
	struct sockaddr_in serverAttributes; 
	if((_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR) {
		cout << Timestamp() << "Error: Unable to open socket: " << WSAGetLastError() << endl;
		return false;
	}
	if((host_entry = gethostbyname(_server)) == NULL) {
		cout << Timestamp() << "Error: Could not find host for server " << _server << ": " << WSAGetLastError() << endl;
		return false;
	}
	serverAttributes.sin_family = AF_INET;
	serverAttributes.sin_port = htons((u_short)_port);
	serverAttributes.sin_addr.s_addr = *(unsigned long*)host_entry->h_addr; 
	if(connect(_socket, (sockaddr *)&serverAttributes, sizeof(serverAttributes)) == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) {
		cout << Timestamp() << "Error: could not connect to server " << _server << ": " << WSAGetLastError() << endl;
		return false;
	}
	if((_socketEvent = CreateEvent(0, 0, 0, 0)) == NULL) {
		cout << Timestamp() << "Error: could not create a valid socket event: " << GetLastError() << endl;
		return false;
	}
	if(WSAEventSelect(_socket, _socketEvent, FD_CONNECT|FD_CLOSE) == SOCKET_ERROR) { // set specified event flags to whatever...
		cout << Timestamp() << "Error: could not select events: " << WSAGetLastError() << endl;
		return false;
	}
	return true; // output connection success message in DoEvents under flag FD_CONNECT
}

bool __stdcall Connection::DisconnectSocket()
{
	if(_socket == SOCKET_ERROR) {
		cout << Timestamp() << "Error: Socket is already disconnected!" << endl;
		return false;
	}
	if(shutdown(_socket, SD_BOTH) == SOCKET_ERROR) {
		cout << Timestamp() << "Error: Could not disconnect socket from server " << _server << ": " << WSAGetLastError() << endl;
		return false;
	}
	return true; // output disconnection success message in DoEvents under flag FD_CLOSE
}

void __stdcall Connection::SendPacket(BufferWriter* message)
{
	if(send(_socket, message->BuildPacket(), (int)message->GetBufferPosition(), 0) == SOCKET_ERROR) {
		cout << Timestamp() << "Error: Could not send data to server " << _server << ": " << GetLastError() << endl;
		DisconnectSocket();
	} else
		global->_bnetConnect->_sentPackets++;
}

void __stdcall Connection::RecvComplete(unsigned long dwError, unsigned long dwTransferred, LPWSAOVERLAPPED lpOverlapped, unsigned long flags)
{
	if(dwTransferred == 0) // disconnected from remote host
		return; // disconnect handling code in FD_CLOSE in DoEvents

	_buflen += dwTransferred; // the size of our current buffer (new data only)
	ProcessData(&_recvBuffer[_bufstart]); // pass the buffer to ProcessData for action starting at _bufstart

	if((signed)((sizeof(_recvBuffer) - (_bufstart + _buflen)) < (dwTransferred << 1) + 120)) {
		memmove(_recvBuffer, &_recvBuffer[_bufstart], _buflen);
		_bufstart = 0;
	}

	_WSARecvBuf.buf = &_recvBuffer[_bufstart + _buflen];
	_WSARecvBuf.len = sizeof(_recvBuffer) - (_bufstart + _buflen);

	if(WSARecv(_socket, &_WSARecvBuf, 1, &_bytes, &_flags, &_recvOv, StaticRecvComplete) == SOCKET_ERROR && GetLastError() != WSA_IO_PENDING) {
		cout << Timestamp() << "Error: Could not receive data from server " << _server << ": " << GetLastError() << endl;
		DisconnectSocket();
	}
}

void __stdcall Connection::SendComplete(unsigned long dwError, unsigned long dwTransferred, LPWSAOVERLAPPED lpOverlapped, unsigned long flags)
{
	if(dwTransferred) // connection refused to accept data
		return; // disconnect handling code in FD_CLOSE in DoEvents

	// ...
}

These is the BufferReader and BufferWriter classes; all functions are inlined into the header file:
Code:
#include "Includes.h"

#ifndef BUFFERREADER_H
#define BUFFERREADER_H

class BufferReader {

public:

	explicit __stdcall BufferReader(const PVOID data, SIZE_T size) : _Buffer((const char*)data), _BufferSize(size), _BufferPosition(0)
	{
		// ...
	}

	__stdcall ~BufferReader()
	{
		// ...
	}

	// all functions explicitly declared with __inline are to be noted as inline

	// extract a unsigned char from the current buffer position and advance
	__inline void __stdcall ExtractData(unsigned char& data)
	{
		CheckBuffer(sizeof(unsigned char));
		data = (unsigned char)_Buffer[_BufferPosition];
		_BufferPosition += sizeof(unsigned char);
	}

	// extract a unsigned short from the current buffer position and advance
	__inline void __stdcall ExtractData(unsigned short& data)
	{
		CheckBuffer(sizeof(unsigned short));
		data = *(const unsigned short*)&_Buffer[_BufferPosition];
		_BufferPosition += sizeof(unsigned short);
	}

	// extract a unsigned long from the current buffer position and advance
	__inline void __stdcall ExtractData(unsigned long& data)
	{
		CheckBuffer(sizeof(unsigned long));
		data = *(const unsigned long*)&_Buffer[_BufferPosition];
		_BufferPosition += sizeof(unsigned long);
	}

	// extract a ULONGLONG from the current buffer position and advance
	__inline void __stdcall ExtractData(ULONGLONG& data)
	{
		CheckBuffer(sizeof(ULONGLONG));
		data = *(const ULONGLONG*)&_Buffer[_BufferPosition];
		_BufferPosition += sizeof(ULONGLONG);
	}

	// extract untyped data from the current buffer position and advance
	__inline void __stdcall ExtractData(PVOID data, SIZE_T size)
	{
		CheckBuffer(size);
		memcpy(data, &_Buffer[_BufferPosition], size);
		_BufferPosition += size;
	}

	// extract a null-terminated ANSI string from the current buffer position and advance
	__inline void __stdcall ExtractData(const char*& data)
	{
		data = (const char*)&_Buffer[_BufferPosition];
		const char* StrEnd = (const char*)memchr(&_Buffer[_BufferPosition], '\0', _BufferSize - _BufferPosition);

		if(!StrEnd) {
			cout << "Buffer overrun error!  Data extraction failed!" << endl;
			return;
		}

		_BufferPosition += StrEnd - &_Buffer[_BufferPosition] + 1;
	}

	// extract a null-terminated std::string from the current buffer position and advance
	__inline void __stdcall ExtractData(std::string& data)
	{
		data = (const char*)&_Buffer[_BufferPosition];
		const char* StrEnd = (const char*)memchr(&_Buffer[_BufferPosition], '\0', _BufferSize - _BufferPosition);

		if(!StrEnd) {
			cout << "Buffer overrun error!  Data extraction failed!" << endl;
			return;
		}

		_BufferPosition += StrEnd - &_Buffer[_BufferPosition] + 1;
	}

	// extract a null-terminated Unicode string from the current buffer position and advance
	__inline void __stdcall ExtractData(PCWSTR& data)
	{
		PCWSTR StrEnd = wmemchr((const PWCHAR)&_Buffer[_BufferPosition], L'\0', (_BufferSize - _BufferPosition) >> 1);
		data = (PCWSTR)&_Buffer[_BufferPosition];

		if(!StrEnd) {
			cout << "Buffer overrun error!  Data extraction failed!" << endl;
			return;
		}

		_BufferPosition += (const char*)StrEnd - &_Buffer[_BufferPosition] + 2;
	}

	// extract a null-terminated std::wstring from the current buffer position and advance
	__inline void __stdcall ExtractData(std::wstring& data)
	{
		PCWSTR StrEnd = wmemchr((const PWCHAR)&_Buffer[_BufferPosition], L'\0', (_BufferSize - _BufferPosition) >> 1);
		data = (PCWSTR)&_Buffer[_BufferPosition];

		if(!StrEnd) {
			cout << "Buffer overrun error!  Data extraction failed!" << endl;
			return;
		}

		_BufferPosition += (const char*)StrEnd - &_Buffer[_BufferPosition] + 2;
	}


	const char* GetBuffer() const
	{
		return _Buffer;
	}

	SIZE_T GetBufferSize() const
	{
		return _BufferSize;
	}

	SIZE_T GetBufferPosition() const
	{
		return _BufferPosition;
	}

	void SetBufferPosition(SIZE_T pos)
	{
		if(pos > _BufferSize)
			return;

		_BufferPosition = pos;
	}

private:
	__inline void __stdcall CheckBuffer(SIZE_T bytes)
	{
		if(_BufferPosition + bytes > _BufferSize)
			cout << "Buffer overrun error!  Attempted to read past the buffer allocation!" << endl;
	}

	// returns false if a buffer overrun would occur
	__inline bool __stdcall CanAdvance(SIZE_T bytes)
	{
		return _BufferPosition + bytes <= _BufferSize;
	}

	const char* _Buffer;
	SIZE_T _BufferSize;
	mutable SIZE_T _BufferPosition;
};

#endif


#include "Includes.h"

#ifndef BUFFERWRITER_H
#define BUFFERWRITER_H

class BufferWriter {

public:

	explicit __stdcall BufferWriter(SIZE_T size = 1024) : _BufferSize(size), _BufferPosition()
	{
		_Buffer = new char[size];

		if(!_Buffer)
			cout << "Out of memory error in attempt to allocate a buffer" << endl;

		ZeroMemory(_Buffer, sizeof(_Buffer));
	}

	virtual __stdcall ~BufferWriter(void)
	{
		delete [] _Buffer;
	}


	// all functions explicitly declared with __inline are to be noted as inline


	// used to build a buffered packet; overrided as a pure virtual function in derived classes
	__inline virtual char* __stdcall BuildPacket(void) = 0;

	// insert an UCHARacter (byte) into the buffer
	__inline void __stdcall InsertData(unsigned char data)
	{
		CheckBuffer(sizeof(unsigned char));
		_Buffer[_BufferPosition] = data;
		_BufferPosition += sizeof(unsigned char);
	}

	// insert an unsigned short (unsigned short) into the buffer
	__inline void __stdcall InsertData(unsigned short data)
	{
		CheckBuffer(sizeof(unsigned short));
		*(PUSHORT)&_Buffer[_BufferPosition] = data;
		_BufferPosition += sizeof(unsigned short);
	}

	// insert an unsigned long (unsigned long) into the buffer
	__inline void __stdcall InsertData(unsigned long data)
	{
		CheckBuffer(sizeof(unsigned long));
		*(PULONG)&_Buffer[_BufferPosition] = data;
		_BufferPosition += sizeof(unsigned long);
	}

	// insert a 64-bit unsigned long (__int64 && ULONGLONG) into the buffer
	__inline void __stdcall InsertData(ULONGLONG data)
	{
		CheckBuffer(sizeof(ULONGLONG));
		*(PULONGLONG)&_Buffer[_BufferPosition] = data;
		_BufferPosition += sizeof(ULONGLONG);
	}

	// insert untyped data of any specified size into the buffer; if default size is 0 the function returns
	__inline void __stdcall InsertData(const PVOID data, SIZE_T size)
	{
		CheckBuffer(size);
		memcpy(&_Buffer[_BufferPosition], data, size);
		_BufferPosition += size;
	}

	// insert an ANSI string (CHARacter array) into the buffer
	__inline void __stdcall InsertData(const char* data)
	{
		SIZE_T len = (SIZE_T)strlen(data)+1;
		CheckBuffer(len);
		memcpy(&_Buffer[_BufferPosition], data, len);
		_BufferPosition += len;
	}

	// insert an ANSI string (std::string) into the buffer
	__inline void __stdcall InsertData(const std::string& data)
	{
		SIZE_T len = (SIZE_T)data.size()+1;
		CheckBuffer(len);
		memcpy(&_Buffer[_BufferPosition], data.c_str(), len);
		_BufferPosition += len;
	}

	// insert a Unicode string (CHARacter array) into the buffer
	__inline void __stdcall InsertData(PCWSTR data)
	{
		SIZE_T len = ((SIZE_T)wcslen(data) << 1) + 2;
		CheckBuffer(len);
		memcpy(&_Buffer[_BufferPosition], data, len);
		_BufferPosition += len;
	}

	// insert a Unicode string (std::string) into the buffer
	__inline void __stdcall InsertData(const std::wstring& data)
	{
		SIZE_T len = (data.size() << 1) + 2;
		CheckBuffer(len);
		memcpy(&_Buffer[_BufferPosition], data.c_str(), len);
		_BufferPosition += len;
	}


	// return the size of the allocated buffer
	SIZE_T GetBufferSize(void) const
	{
		return _BufferSize;
	}

	// return the current buffer insert position
	SIZE_T GetBufferPosition(void) const
	{
		return _BufferPosition;
	}

	// return a pointer to the buffer
	char* GetBuffer(void) const
	{
		return _Buffer;
	}

	
	void SetBufferPosition(unsigned long Position)
	{
		if(Position > _BufferSize)
			CheckBuffer(Position);

		_BufferPosition = Position;
	}


	// resize the current buffer to make room for more data
	__inline void __stdcall ResizeBuffer(SIZE_T size)
	{
		char* temp_buf = (char*)realloc(_Buffer, size);

		if(!temp_buf) {
			cout << "Out of memory error in attempt to allocate a buffer!  Buffer resize failed!" << endl;
			return;
		}

		_Buffer = temp_buf;
	}

protected:

	// check to see if the buffer needs to be resized
	__inline void __stdcall CheckBuffer(SIZE_T requiredBytes)
	{
		if(_BufferPosition + requiredBytes > _BufferSize)
			ResizeBuffer((_BufferSize << 1) > _BufferPosition + requiredBytes ? _BufferSize << 1 : _BufferPosition + requiredBytes + (_BufferSize << 1));
	}

	char* _Buffer;
	SIZE_T _BufferSize, _BufferPosition;
};


#endif

This is my BotMain() function called after all the prerequisites are completed (irrelevant to the problem)in main():
Code:
void __cdecl BotMain(void)
{
	global->_bnetConnect = new BnetConnection(global->_server, 6112);
	if(global->_bnls)
		global->_bnlsConnect = new BNLSConnection(global->_bnlsServer, 9367);

	strcpy(global->_botData._username, global->_username);
	global->_queueThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)QueueThread, NULL, NULL, NULL);

	WSAData wsaData;
	if(WSAStartup(MAKEWORD(2, 2), &wsaData) == SOCKET_ERROR) {
		cout << Timestamp() << "Error: could not startup Winsock: " << WSAGetLastError() << endl;
	}
	
	cout << Timestamp() << "Connecting to Battle.net server " << global->_server << "..." << endl;
	
	while(global->_bnetConnect->ConnectSocket() == false)
		Sleep(5000);
	global->_socketEvents[0] = global->_bnetConnect->GetSocketEvent();
	
	if(global->_bnls) {
		cout << Timestamp() << "Connecting to BNLS server " << global->_bnlsServer << "..." << endl;
		while(global->_bnlsConnect->ConnectSocket() == false)
			Sleep(5000);
		global->_socketEvents[1] = global->_bnlsConnect->GetSocketEvent();
	}

	if(global->_bnls) {
		while(global->_shutdownBot == false) {
			unsigned long waitResult = WaitForMultipleObjectsEx(2, global->_socketEvents, false, INFINITE, true);
			switch(waitResult) {
				case WAIT_OBJECT_0 + (1 - 1):
					global->_bnetConnect->DoEvents();
					break;
				case WAIT_OBJECT_0 + (2 - 1):
					global->_bnlsConnect->DoEvents();
					break;
				case WAIT_FAILED:
					cout << Timestamp() << "Error: Could not wait on event handles: " << GetLastError() << endl;
					break;
				case WAIT_TIMEOUT:
					cout << Timestamp() << "Error: A timeout occured on waiting for an object event: " << GetLastError() << endl;
					break;
				case WAIT_IO_COMPLETION:
					//cout << Timestamp() << "Warning: A wait function returned to an asynchronous procedure call (APC): " << GetLastError() << endl;
					break;
				case WAIT_ABANDONED_0:
					cout << Timestamp() << "Warning: An object handle was abandoned while waiting on it: " << GetLastError() << endl;
					break;
				default:
					cout << Timestamp() << "Error: An unknown error occured when waiting on the object handles: " << GetLastError() << endl;
					break;
			}
			Sleep(0);
		}
	} else if(!global->_bnls) {
		while(global->_shutdownBot == false) {
			unsigned long waitResult = WaitForMultipleObjectsEx(1, &global->_socketEvents[0], false, INFINITE, true);
			switch(waitResult) {
				case WAIT_OBJECT_0 + (1 - 1):
					global->_bnetConnect->DoEvents();
					break;
				case WAIT_FAILED:
					cout << Timestamp() << "Error: Could not wait on event handles: " << GetLastError() << endl;
					break;
				case WAIT_TIMEOUT:					
					cout << Timestamp() << "Error: A timeout occured on waiting for an object event: " << GetLastError() << endl;
					break;
				case WAIT_IO_COMPLETION:
					//cout << Timestamp() << "Warning: A wait function returned to an asynchronous procedure call (APC): " << GetLastError() << endl;
					break;
				case WAIT_ABANDONED_0:
					cout << Timestamp() << "Warning: An object handle was abandoned while waiting on it: " << GetLastError() << endl;
					break;
				default:
					cout << Timestamp() << "Error: An unknown error occured when waiting on the object handles: " << GetLastError() << endl;
					break;
			}
			Sleep(0);
		}
	}
}

These are the relevant functions from BnetConnection which derives from Connection:
Code:
bool __stdcall BnetConnection::DoEvents()
{
	WSANETWORKEVENTS *events = new WSANETWORKEVENTS;
	WSAEnumNetworkEvents(_socket, _socketEvent, events);

	if(events->lNetworkEvents & FD_CONNECT) {
		cout << Timestamp() << "Connected to server " << _server << "!" << endl;
		SendProtocolByte();

		memset(&_recvOv, 0, sizeof(_recvOv));
		_recvOv.hEvent = (HANDLE)this;
		_WSARecvBuf.buf = _recvBuffer;
		_WSARecvBuf.len = sizeof(_recvBuffer);

		if(WSARecv(_socket, &_WSARecvBuf, 1, &_bytes, &_flags, &_recvOv, StaticRecvComplete) == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) {
			cout << Timestamp() << "Initial WSARecv failed: " << WSAGetLastError() << endl;
			DisconnectSocket();
			if(global->_autoreconnect) {
				Sleep(5000);
				BotMain();
			}
			return false;
		}
	} else if(events->lNetworkEvents & FD_CLOSE) {
		cout << Timestamp() << "Disconnected from server " << _server << "!" << endl;
		closesocket(_socket);
		if(global->_autoreconnect) {
			Sleep(5000);
			BotMain();
		}
	}
	return true;
}

void __stdcall BnetConnection::ProcessData(char* buffer)
{
	unsigned char serverID = '\0';
	unsigned char packetID = '\0';
	unsigned short packetlen = 0;
	char data[BUFFER_SIZE] = {0};
	BufferReader *pRead = new BufferReader(buffer, _buflen);

	while(_buflen >= 4 && _buflen >= packetlen) {
			pRead->ExtractData(serverID);
			pRead->ExtractData(packetID);
			pRead->ExtractData(packetlen);
			pRead->ExtractData(data, packetlen-4);

		//cout << Timestamp() << "Received packet 0x" << hex << (unsigned long)packetID << " from Battle.net." << endl << dec;

		if(serverID != 0xFF) {
			cout << Timestamp() << "Error: Received invalid packet class: " << hex << (unsigned long)serverID << endl << dec;
			DisconnectSocket();
			return;
		}

		ProcessMessages(packetID, data, packetlen-4);
		_buflen -= packetlen;
		_bufstart += packetlen;
	}
	delete pRead;
}

I realize that it's a lot to go through and potential impossible to determine the error without being able to debug, but yeah...If decide to go through it and propose any solutions I'd appreciate it (and even point out coding inconsistancies, bad coding practice, etc. I'd appreciate that as well). Again the problem is that there are some disconnects caused by buffering problems; in the logs it stores (from redirecting output from std) it has a lot of errors reported by the BufferReader class which is almost always followed by a disconnection.