예제 #1
0
파일: Client.cs 프로젝트: jon-hyland/games
        /// <summary>
        /// Reads data from incoming stream (if bytes exist in buffer).  Tries to construct
        /// one or more game packets. Fires event for each valid game packet.
        /// </summary>
        private void ReadData()
        {
            try
            {
                //vars
                List <byte[]> packets = new List <byte[]>();

                //lock queue
                lock (_incomingQueue)
                {
                    //return if zero bytes
                    if (_incomingQueue.Count == 0)
                    {
                        return;
                    }

                    //queue overflow?
                    if (_incomingQueue.Count > 100000)
                    {
                        Log.Write($"ReadData: Incoming byte queue overflow");
                        _incomingQueue.Clear();
                    }

                    //loop
                    while (true)
                    {
                        //break if zero bytes
                        if (_incomingQueue.Count == 0)
                        {
                            break;
                        }

                        //find first four matching footer bytes (terminator)
                        int firstIndex = FindToken(_incomingQueue, PacketBase.PACKET_FOOTER);

                        //break if no footer
                        if (firstIndex == -1)
                        {
                            Log.Write($"ReadData: Incomplete data ({_incomingQueue.Count} bytes) left in buffer");
                            break;
                        }

                        //dequeue bytes
                        int    count = firstIndex + 4;
                        byte[] bytes = _incomingQueue.Dequeue(count).ToArray();

                        //add to list
                        packets.Add(bytes);
                    }
                }

                //return if no new packets
                if (packets.Count <= 0)
                {
                    return;
                }

                //loop through packet (candidates)
                foreach (byte[] bytes in packets)
                {
                    //reject if invalid
                    PacketBase packet = PacketBase.FromBytes(bytes);
                    if (packet == null)
                    {
                        Log.Write($"ReadData: Invalid packet from '{_remoteIP}' with {bytes.Length} bytes was discarded");
                        continue;
                    }

                    //fire event
                    PacketReceived?.InvokeFromTask(this, packet);   //WARNING, CHANGED THIS!!
                }
            }
            catch (Exception ex)
            {
                _stop = true;
                Log.Write("ReadData: Error reading or processing data");
                ErrorHandler.LogError(ex);
            }
        }