Example #1
0
        /// <summary>
        /// Socket transmit thread
        /// </summary>
        public void TxThread()
        {
            // Execute until a kill event occurs
            while (!m_transmitThreadInfo.m_pKill.WaitOne(5, false))
            {
                try
                {
                    // Check the reliable message queue for retransmits
                    Byte[] pReliableData = m_reliableMessageHandler.GetRetransmitPacket();

                    // If a packet is found
                    if (pReliableData.Length > 0)
                    {
                        // Add the message to the transmit queue
                        TransmitPacket(pReliableData);
                    }

                    if (m_pTransmitQueue.Count != 0)
                    {
                        // Check if there is more than one packet
                        if (m_pTransmitQueue.Count > 1)
                        {
                            // Create a clustered packet
                            ClusteredPacket packetCluster = new ClusteredPacket();

                            while (m_pTransmitQueue.Count > 0)
                            {
                                // Get the next packet
                                Byte[] nextPacket = (Byte[])(m_pTransmitQueue[0]);

                                if (nextPacket != null)
                                {
                                    // If the packet is too big to cluster
                                    if (nextPacket.Length > 256)
                                    {
                                        // Encrypt and transmit the packet
                                        EncryptAndTransmitPacket(nextPacket);
                                    }
                                    else
                                    {
                                        // Add the next packet to the cluster
                                        packetCluster.AddPacket(nextPacket);

                                        if (packetCluster.ClusterLength > 256)
                                        {
                                            // Encrypt and transmit the packet
                                            EncryptAndTransmitPacket(packetCluster.Packet);
                                        }
                                    }
                                }
                                // Remove the item from the queue
                                m_pTransmitQueue.RemoveAt(0);
                            }

                            if (packetCluster.ClusterLength > 0)
                            {
                                // Encrypt and transmit the packet
                                EncryptAndTransmitPacket(packetCluster.Packet);
                            }
                        }
                        else
                        {
                            // Encrypt and transmit the packet
                            EncryptAndTransmitPacket((Byte[])(m_pTransmitQueue[0]));

                            // Remove the item from the queue
                            m_pTransmitQueue.RemoveAt(0);
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    m_receiveThreadInfo.m_pKill.Set();
                    m_transmitThreadInfo.m_pKill.Set();
                }
            }

            try
            {
                // Send any outstanding messages
                while (m_pTransmitQueue.Count > 0)
                {
                    // Get the next packet to transmit
                    Byte[] pData = (Byte[])(m_pTransmitQueue[0]);

                    // Encrypt the next packet
                    pData = m_packetEncryption.Encrypt(pData);

                    // Send the packet to the server
                    m_pSocket.Send(pData, pData.Length);

                    // Remove the item from the queue
                    m_pTransmitQueue.RemoveAt(0);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            // Reset the kill event
            m_transmitThreadInfo.m_pKill.Reset();

            // Set the thread dead event
            m_transmitThreadInfo.m_pDead.Set();
        }
Example #2
0
        /// <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);
        }