Пример #1
0
        static void Main(string[] args)
        {
            Program prog = new Program(args);

            if (prog.ShowUsage)
            {
                Usage();
                return;
            }

            if (prog.ArgsOk)
            {
                FrameDisplay frameDisplay = new FrameDisplay();
                try
                {
                    prog.Run(frameDisplay);
                }
                finally
                {
                    // Ensure frameDisplay thread terminates.
                    frameDisplay.Stop();
                }
            }
            else
            {
                Usage();
            }
        }
Пример #2
0
        public void Run(FrameDisplay frameDisplay)
        {
            int                   connectionPollTimeSecMs = 250;
            TcpClient             socket          = null;
            PacketBuffer          packetBuffer    = null;
            CollatedPacketDecoder collatedDecoder = new CollatedPacketDecoder();
            BinaryWriter          recordingWriter = null;

#if PACKET_TIMING
            Stopwatch timer = new Stopwatch();
#endif // PACKET_TIMING
            bool once = true;

            Console.CancelKeyPress += new ConsoleCancelEventHandler(ControlCHandler);

            if (!Quiet)
            {
                Console.WriteLine(string.Format("Connecting to {0}", ServerEndPoint));
            }

            while (!Quit && (Persist || once))
            {
                once = false;
                // First try establish a connection.
                while (!Quit && !Connected)
                {
                    if ((socket = AttemptConnection()) != null)
                    {
#if PACKET_TIMING
                        timer.Reset();
                        timer.Start();
#endif // PACKET_TIMING
                        TotalFrames = 0u;
                        frameDisplay.Reset();
                        if (!Quiet)
                        {
                            frameDisplay.Start();
                        }
                        recordingWriter = CreateOutputWriter();
                        if (recordingWriter != null)
                        {
                            Connected = true;
                            // Create a new packet buffer for this connection.
                            packetBuffer = new PacketBuffer(4 * 1024);
                        }
                        Log.Flush();
                    }
                    else
                    {
                        Log.Flush();
                        // Wait the timeout period before attempting to reconnect.
                        System.Threading.Thread.Sleep(connectionPollTimeSecMs);
                    }
                }

                // Read while connected or data still available.
                while (!Quit && socket != null && (TcpClientUtil.Connected(socket) || socket.Available > 0))
                {
                    // We have a connection. Read messages while we can.
                    if (socket.Available > 0)
                    {
                        // Data available. Read from the network stream into a buffer and attempt to
                        // read a valid message.
                        packetBuffer.Append(socket.GetStream(), socket.Available);
                        PacketBuffer completedPacket;
                        bool         exportPacket = true;
                        bool         crcOk        = true;
                        while ((completedPacket = packetBuffer.PopPacket(out crcOk)) != null || !crcOk)
                        {
                            if (crcOk)
                            {
                                if (packetBuffer.DroppedByteCount != 0)
                                {
                                    Console.Error.WriteLine("Dropped {0} bad bytes", packetBuffer.DroppedByteCount);
                                    packetBuffer.DroppedByteCount = 0;
                                }

                                if (DecodeMode == Mode.Passthrough)
                                {
                                    completedPacket.ExportTo(recordingWriter);
                                    // Approximate packets as frames. Not exactly correct though.
                                    if (completedPacket.Header.RoutingID == (ushort)RoutingID.Control)
                                    {
                                        if (completedPacket.Header.MessageID == (ushort)ControlMessageID.EndFrame)
                                        {
                                            ++TotalFrames;
                                            frameDisplay.IncrementFrame();
#if PACKET_TIMING
                                            if (TotalFrames >= PacketLimit)
                                            {
                                                timer.Stop();
                                                Quit = true;
                                            }
#endif // PACKET_TIMING
                                        }
                                    }
                                    continue;
                                }

                                // Decode and decompress collated packets. This will just return the same packet
                                // if not collated.
                                collatedDecoder.SetPacket(completedPacket);
                                while ((completedPacket = collatedDecoder.Next()) != null)
                                {
                                    //Console.WriteLine("Msg: {0} {1}", completedPacket.Header.RoutingID, completedPacket.Header.MessageID);
                                    switch (completedPacket.Header.RoutingID)
                                    {
                                    case (ushort)RoutingID.Control:
                                        ushort controlMessageId = completedPacket.Header.MessageID;
                                        if (controlMessageId == (ushort)ControlMessageID.EndFrame)
                                        {
                                            ++TotalFrames;
                                            frameDisplay.IncrementFrame();
#if PACKET_TIMING
                                            if (TotalFrames >= PacketLimit)
                                            {
                                                timer.Stop();
                                                Quit = true;
                                            }
#endif // PACKET_TIMING
                                        }
                                        break;

                                    case (ushort)RoutingID.ServerInfo:
                                        NetworkReader packetReader = new NetworkReader(completedPacket.CreateReadStream(true));
                                        _serverInfo.Read(packetReader);
                                        exportPacket = false;
                                        break;

                                    default:
                                        break;
                                    }

                                    if (exportPacket)
                                    {
                                        completedPacket.ExportTo(recordingWriter);
                                    }
                                }
                            }
                            else
                            {
                                Console.Error.WriteLine("CRC Failure");
                                // TODO: Log CRC failure.
                            }
                        }
                        Log.Flush();
                    }
                    else
                    {
                        Log.Flush();
                        System.Threading.Thread.Sleep(0);
                    }
                }

                frameDisplay.Stop();

                if (packetBuffer != null && packetBuffer.DroppedByteCount != 0)
                {
                    Console.Error.WriteLine("Dropped {0} bad bytes", packetBuffer.DroppedByteCount);
                    packetBuffer.DroppedByteCount = 0;
                }

                if (recordingWriter != null)
                {
                    FinaliseOutput(recordingWriter, TotalFrames);
                    recordingWriter.Flush();
                    recordingWriter.Close();
                    recordingWriter = null;
                }

                if (!Quiet)
                {
                    Console.WriteLine("Connection closed");
                }

                // Disconnected.
                if (socket != null)
                {
                    socket.Close();
                    socket = null;
                }

                Connected = false;

                // GC to force flushing streams and collect other resource.
                GC.Collect();
            }

#if PACKET_TIMING
            Console.WriteLine($"Processed {PacketLimit} packets in {timer.ElapsedMilliseconds}ms");
#endif // PACKET_TIMING
        }