// 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(); } } }