예제 #1
0
        // REVIEW: Leverage marshalling for this.
        public static GatewayPayload From(byte[] arrPayload)
        {
            GatewayPayload payload = new GatewayPayload();

            // Create a BinaryReader around the incoming array to parse the data out of it
            MemoryStream msPayload = new MemoryStream(arrPayload);
            BinaryReader reader    = new BinaryReader(msPayload);

            payload.Mode = (BlockMode)reader.ReadUInt32();
            if (!payload.IsModeAboutVolumeStatus())
            {
                payload.OffsetToRW     = reader.ReadUInt32();
                payload.LengthRW       = reader.ReadUInt32();
                payload.LengthDeviceID = reader.ReadUInt32();

                // Read the deviceID string
                byte[] arrDeviceID = reader.ReadBytes((int)payload.LengthDeviceID);
                unsafe
                {
                    fixed(byte *pDeviceID = arrDeviceID)
                    {
                        IntPtr ptrDeviceID = new IntPtr(pDeviceID);

                        payload.DeviceID = Marshal.PtrToStringUni(ptrDeviceID);
                    }
                }
            }

            // Finally, if the payload is for writing, get the payload data
            if (payload.Mode == BlockMode.Write)
            {
                payload.PayloadData = reader.ReadBytes((int)payload.LengthRW);
            }

            if (!payload.IsModeAboutVolumeStatus())
            {
                // Fetch the EndOfPayloadMarker
                payload.EndOfPayloadMarker = reader.ReadUInt32();
            }

            reader.Close();

            return(payload);
        }
        private void ProcessTcpClient(CancellationToken cancellationToken, TcpClient tcpClient)
        {
            if (!cancellationToken.IsCancellationRequested)
            {
                NetworkStream ns        = null;
                byte[]        arrData   = null;
                int           readBytes = 0;

                try
                {
                    try
                    {
                        ns = tcpClient.GetStream();
                    }
                    catch (InvalidOperationException)
                    {
                        Console.WriteLine("ProcessTCPClient: Unable to get NetworkStream to read data!");
                        tcpClient.Close();
                        ns = null;
                    }

                    while ((ns != null) && (tcpClient.Connected) && (!cancellationToken.IsCancellationRequested))
                    {
                        arrData = new byte[GatewayPayloadConst.payloadBufferSizeMax];

                        int iOffsetToReadInto      = 0;
                        int iBufferAvailableLength = GatewayPayloadConst.payloadBufferSizeMax;
                        int iTotalRead             = 0;

                        readBytes = ns.Read(arrData, iOffsetToReadInto, iBufferAvailableLength);
                        while (readBytes > 0)
                        {
                            // Increment the total bytes read
                            iTotalRead += readBytes;

                            iOffsetToReadInto      += readBytes;
                            iBufferAvailableLength -= readBytes;
                            if (iBufferAvailableLength > 0)
                            {
                                readBytes = ns.Read(arrData, iOffsetToReadInto, iBufferAvailableLength);
                            }
                            else
                            {
                                Console.WriteLine("ProcessTCPClient: Read buffer full.");
                                break;
                            }
                        }

                        if (iTotalRead > 0)
                        {
                            Console.WriteLine("ProcessTCPClient: Read {0} bytes", iTotalRead);

                            GatewayPayload payload = GatewayPayload.From(arrData);

                            // Process the payload
                            try
                            {
                                payload.ProcessPayloadBlock(bsManager);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("ProcessTCPClient: Got an exception [{0} - {1}] while processing payload.", ex.GetType().ToString(), ex.Message);

                                // Build the payload information to be dumped.
                                StringBuilder sbPayloadInfo = new StringBuilder();
                                sbPayloadInfo.AppendLine(String.Format("Mode: {0:X}", payload.Mode));
                                sbPayloadInfo.AppendLine(String.Format("Offset: {0:X}", payload.OffsetToRW));
                                sbPayloadInfo.AppendLine(String.Format("Length to R/W: {0:X}", payload.LengthRW));
                                sbPayloadInfo.AppendLine(String.Format("DeviceID Length: {0:X}", payload.LengthDeviceID));
                                sbPayloadInfo.AppendLine(String.Format("DeviceID: {0}", payload.DeviceID));
                                sbPayloadInfo.AppendLine(String.Format("EndOfPayloadMarker: {0:X}", payload.EndOfPayloadMarker));

                                Console.WriteLine(sbPayloadInfo.ToString());

                                // Payload processing failed - Reflect in the payload status
                                payload.LengthRW = 0;
                                if (payload.EndOfPayloadMarker != GatewayPayloadConst.EndOfPayloadMarker)
                                {
                                    // We got a payload that was invalid, so reflect that
                                    // in the mode we will send back
                                    payload.Mode = BlockMode.ServerInvalidPayload;
                                    Console.WriteLine("ProcessTCPClient: Client sent an invalid payload.");
                                }
                                else
                                {
                                    payload.Mode = BlockMode.OperationFailed;
                                }
                            }

                            // Send the Data back to the sender
                            byte[] arrDataToSendBack = payload.ToArray();
                            ns.Write(arrDataToSendBack, 0, arrDataToSendBack.Length);
                        }
                    }
                }
                catch (IOException)
                {
                    // Network connection was closed
                }
                catch (ObjectDisposedException)
                {
                    // Network connection was closed
                }
                catch (Exception ex)
                {
                    Console.WriteLine("ProcessTCPClient: Got an exception [{0} - {1}] while handling incoming request.", ex.GetType().ToString(), ex.Message);
                }

                // If we are here, we are not in a position to process the network requests and thus, should close
                // the connection.
                if (tcpClient != null)
                {
                    tcpClient.Close();
                }
            }
        }