/// <summary> /// Receive a packet from the server /// </summary> /// <returns>Received packet data</returns> public Byte[] ReceivePacket() { ReliablePacket pReliablePacket = new ReliablePacket(); AcknowlegePacket pAckPacket = new AcknowlegePacket(); Byte[] pData = new Byte[0]; ClusteredPacket pClusteredPacket = new ClusteredPacket(); ChunkBodyPacket pChunkBodyPacket = new ChunkBodyPacket(); ChunkTailPacket pChunkTailPacket = new ChunkTailPacket(); LargeChunkPacket pLargeChunkPacket = new LargeChunkPacket(); // Check if there are any elements on the queue if (m_pReceiveQueue.Count > 0) { // Get the next element from the receive queue pData = (Byte[])(m_pReceiveQueue.Dequeue()); if (pData != null) { // Write the data to the packet loggers m_packetLogger(PacketDirection.Receive, pData); // Check if the message is reliable if (pData[0] == 0x00) { switch (pData[1]) { case 0x03: // Set the packet information pReliablePacket.Packet = pData; // Extract the message pData = pReliablePacket.Message; // Increment the reliable receive counter m_nReliablePacketsReceived++; // Set the acknowlege transaction identifier and transmit pAckPacket.TransactionId = pReliablePacket.TransactionId; TransmitPacket(pAckPacket.Packet); break; case 0x04: // Set the acknowlegement packet data pAckPacket.Packet = pData; // Handle the Acknowlege packet m_reliableMessageHandler.HandleAcknowlegement(pAckPacket.TransactionId); break; } // Check if the packet is a chunk body packet if ((pData[0] == 0x00) && (pData[1] == 0x08)) { // Set the chunk data packet pChunkBodyPacket.Packet = pData; // Get the message packet from the buffer pData = pChunkBodyPacket.Message; // Append the data to the buffer m_chunkBuffer.Write(pData, 0, pData.Length); // Clear the returned data pData = new Byte[0]; } // Check if the packet is a chunk tail packet else if ((pData[0] == 0x00) && (pData[1] == 0x09)) { // Set the chunk data packet pChunkTailPacket.Packet = pData; // Get the message packet from the buffer pData = pChunkTailPacket.Message; // Append the data to the chunk buffer m_chunkBuffer.Write(pData, 0, pData.Length); // return the full data packet pData = m_chunkBuffer.ToArray(); // Clear the chunk buffer m_chunkBuffer.Position = 0; } // Check if the packet is a large chunk packet else if ((pData[0] == 0x00) && (pData[1] == 0x0A)) { // Set the large chunk packet pLargeChunkPacket.Packet = pData; // Get the message packet from the buffer pData = pLargeChunkPacket.Message; // Append the message to the large buffer m_largeBuffer.Write(pData, 0, pData.Length); // Check if the packet is complete if (m_largeBuffer.Length == pLargeChunkPacket.TotalLength) { // return the full data packet pData = m_largeBuffer.ToArray(); // Clear the chunk buffer m_largeBuffer.Position = 0; } else { // Clear the returned data pData = new Byte[0]; } } // Check if the packet is a clustered packet else if ((pData[0] == 0x00) && (pData[1] == 0x0E)) { // Set the clustered packet data pClusteredPacket.Packet = pData; // Get the enumerator for the packet list IEnumerator pEnum = pClusteredPacket.Packets.GetEnumerator(); while (pEnum.MoveNext()) { // Add the next element to the receive queue m_pReceiveQueue.Enqueue((Byte[])pEnum.Current); } // Clear the returned data pData = new Byte[0]; } } } } return(pData); }
/// <summary> /// Transmit a packet to the server /// </summary> /// <param name="pData">packet data</param> public void TransmitPacket(Byte[] pData) { try { // Check if the message should be broken up if (pData.Length > (LargeChunkSize + 12)) { Int32 nPosition = 0; // Current buffer position // Check if this is a large message if (pData.Length > 1000) { // Create the large chunk packet LargeChunkPacket pLargeChunkPacket = new LargeChunkPacket(); // Set the total length of the packet pLargeChunkPacket.TotalLength = (UInt32)pData.Length; while (nPosition < pData.Length) { // Get the remaining length Int32 nLength = Math.Min((pData.Length - nPosition), LargeChunkSize); // Create the message buffer Byte[] pcMessage = new Byte[nLength]; // Copy the data into the new message buffer Array.Copy(pData, nPosition, pcMessage, 0, nLength); // Copy the message data into the Large Chunk packet pLargeChunkPacket.Message = pcMessage; // Get the large chunk packet Byte[] pLargeChunk = pLargeChunkPacket.Packet; // Write the data to the packet loggers m_packetLogger(PacketDirection.Transmit, pLargeChunk); // Add the message to the transmit queue m_pTransmitQueue.Add(pLargeChunk); // Increment the current position nPosition += pcMessage.Length; } } else { // Create the chunked data packets ChunkBodyPacket pChunkBodyPacket = new ChunkBodyPacket(); ChunkTailPacket pChunkTailPacket = new ChunkTailPacket(); while (nPosition < pData.Length) { // Get the remaining length Int32 nLength = Math.Min((pData.Length - nPosition), SmallChunkSize); // Create the message buffer Byte[] pcMessage = new Byte[nLength]; // Copy the data into the new message buffer Array.Copy(pData, nPosition, pcMessage, 0, nLength); // Increment the current position nPosition += nLength; if (pcMessage.Length == SmallChunkSize) { // Copy the message data into the Chunk Body packet pChunkBodyPacket.Message = pcMessage; Byte[] pChunkBody = pChunkBodyPacket.Packet; // Write the data to the packet loggers m_packetLogger(PacketDirection.Transmit, pChunkBody); // Add the message to the transmit queue m_pTransmitQueue.Add(pChunkBody); } else { // Copy the message data into the Chunk Tail packet pChunkTailPacket.Message = pcMessage; // Ge the chunk tail packet Byte[] pChunkTail = pChunkTailPacket.Packet; // Write the data to the packet loggers m_packetLogger(PacketDirection.Transmit, pChunkTail); // Add the message to the transmit queue m_pTransmitQueue.Add(pChunkTail); } } } } else { // Write the data to the packet loggers m_packetLogger(PacketDirection.Transmit, pData); // Add the data to the end of the queue m_pTransmitQueue.Add(pData); } } catch (Exception e) { Console.WriteLine(e); } }