예제 #1
0
void NetSocket::HandleInput()
{
	// read in data from the socket and compose it into discrete packets that the game can read

	bool packetReceived = false;
	u_long packetSize = 0;

	// read the socket into the receiver buffer which acts as a ring buffer
	int rc = recv(m_Sock, m_RecvBuf + m_RecvBegin + m_RecvOffset, RECV_BUFFER_SIZE - (m_RecvBegin + m_RecvOffset), 0);

	if (rc == 0)
	{
		return;
	}
	
	if (rc == SOCKET_ERROR)
	{
		m_DeleteFlag = 1;
		return;
	}

	// header size = 4 bytes
	const int hdrSize = sizeof(u_long);
	// get the end of the new data read in
	unsigned int newData = m_RecvOffset + rc;
	int processedData = 0;

	while (newData > hdrSize)
	{
		// we support two types of packets:
		// Binary packet - size is a positive 4 byte int at the start of data
		// Text packet - size 0, parser searches for carriage return

		// convert the first 4 bytes received to host order - this is the size of this packet
		packetSize = *(reinterpret_cast<u_long*>(m_RecvBuf + m_RecvBegin));
		packetSize = ntohl(packetSize);

		if (m_BinaryProtocol)
		{
			// if the data is less than the packet size, then we haven't finished
			// reading this packet and dont have enough data to get the next packet
			if (newData < packetSize)
			{
				break;
			}
			
			if (packetSize > MAX_PACKET_SIZE)
			{
				// buffer overrun
				HandleException();
				return;
			}

			// we know the packet size and have the entire thing read in
			if (newData >= packetSize)
			{
				// create the packet from the receiver buffer (m_RecvBegin + hrdSize so we dont read the header *size* into the data)
				shared_ptr<BinaryPacket> packet(CB_NEW BinaryPacket(&m_RecvBuf[m_RecvBegin + hdrSize], packetSize - hdrSize));
				m_InList.push_back(packet);
				packetReceived = true;
				processedData += packetSize;
				newData -= packetSize;
				// move the receiver head up by the packet size amount
				m_RecvBegin += packetSize;
			}
		}
		else
		{
			// text protocol waits for a carriage return and creates a string
			// scan the memory we just read for this character
			char* cr = static_cast<char*>(memchr(&m_RecvBuf[m_RecvBegin], 0x0a, rc));
			if (cr)
			{
				// if found, change the '\n' in the text packet to a null terminator
				*(cr + 1) = 0;
				shared_ptr<TextPacket> packet(CB_NEW TextPacket(&m_RecvBuf[m_RecvBegin]));
				m_InList.push_back(packet);
				packetSize = cr - &m_RecvBuf[m_RecvBegin];
				packetReceived = true;
				processedData += packetSize;
				newData -= packetSize;
				// move the receiver head up by the packet size amount
				m_RecvBegin += packetSize;
			}
		}
	}

	g_pSocketManager->AddToInbound(rc);
	m_RecvOffset = newData;

	if (packetReceived)
	{
		if (m_RecvOffset == 0)
		{
			m_RecvBegin = 0;
		}
		else if (m_RecvBegin + m_RecvOffset + MAX_PACKET_SIZE > RECV_BUFFER_SIZE)
		{
			// dont want to allow data to overrun the receiver buffer, so copy leftover bits
			// to the beginning and reset the heads
			int leftover = m_RecvOffset;
			memcpy(m_RecvBuf, &m_RecvBuf[m_RecvBegin], m_RecvOffset);
			m_RecvBegin = 0;
		}
	}
}
예제 #2
0
//
// NetSocket::VHandleInput						- Chapter 19, page 671
//
void NetSocket::VHandleInput() 
{
	bool bPktRecieved = false;
	u_long packetSize = 0;
	int rc = recv(m_sock, m_recvBuf+m_recvBegin+m_recvOfs, RECV_BUFFER_SIZE-(m_recvBegin+m_recvOfs), 0);

	char metrics[1024];
	sprintf_s(metrics, 1024, "Incoming: %6d bytes. Begin %6d Offset %4d\n", rc, m_recvBegin, m_recvOfs);

	std::stringstream ss;
	ss << "Network" << metrics;
    LOG_WRITE(ss.str());

	if (rc==0)
	{
		return;
	}

	if (rc==SOCKET_ERROR)
	{
		m_deleteFlag = 1;
		return;
	}

	const int hdrSize = sizeof(u_long);
	unsigned int newData = m_recvOfs + rc;
	int processedData = 0;

	while (newData > hdrSize)
	{
		// There are two types of packets at the lowest level of our design:
		// BinaryPacket - Sends the size as a positive 4 byte integer
		// TextPacket - Sends 0 for the size, the parser will search for a CR

		packetSize = *(reinterpret_cast<u_long*>(m_recvBuf+m_recvBegin));
		packetSize = ntohl(packetSize);

		if (m_bBinaryProtocol)
		{
			// we don't have enough new data to grab the next packet
			if (newData < packetSize)
				break;

			if (packetSize > MAX_PACKET_SIZE)
			{
				// prevent nasty buffer overruns!
				HandleException();
				return;
			}

			if (newData >= packetSize)
			{
				// we know how big the packet is...and we have the whole thing
				//
				//[mrmike] - a little code to aid debugging network packets here!
				//char test[1024];
				//memcpy(test, &m_recvBuf[m_recvBegin+hdrSize], packetSize);
				//test[packetSize+1]='\r';
				//test[packetSize+2]='\n';
				//test[packetSize+3]=0;
                //LOG_WRITE("Network", test);
				shared_ptr<BinaryPacket> pkt(QSE_NEW BinaryPacket(&m_recvBuf[m_recvBegin+hdrSize], packetSize-hdrSize));
				m_InList.push_back(pkt);
				bPktRecieved = true;
				processedData += packetSize;
				newData -= packetSize;
				m_recvBegin += packetSize;
			}
		}
		else
		{
			// the text protocol waits for a carraige return and creates a string
			char *cr = static_cast<char *>(memchr(&m_recvBuf[m_recvBegin], 0x0a, rc));
			if (cr)
			{
				*(cr+1) = 0;
				shared_ptr<TextPacket> pkt(QSE_NEW TextPacket(&m_recvBuf[m_recvBegin]));
				m_InList.push_back(pkt);
				packetSize = cr - &m_recvBuf[m_recvBegin];
				bPktRecieved = true;

				processedData += packetSize;
				newData -= packetSize;
				m_recvBegin += packetSize;
			}
		}
	}

	g_pSocketManager->AddToInbound(rc);
	m_recvOfs = newData;

	if (bPktRecieved)
	{
		if (m_recvOfs == 0)
		{
			m_recvBegin = 0;
		}
		else if (m_recvBegin + m_recvOfs + MAX_PACKET_SIZE > RECV_BUFFER_SIZE)
		{
			// we don't want to overrun the buffer - so we copy the leftover bits 
			// to the beginning of the recieve buffer and start over
			int leftover = m_recvOfs;
			memcpy(m_recvBuf, &m_recvBuf[m_recvBegin], m_recvOfs);
			m_recvBegin = 0;
		}
	}	
}