From a2f26ecb6be47e129393735e4dab1eca6600b19d Mon Sep 17 00:00:00 2001 From: icedream Date: Thu, 22 May 2014 17:08:07 +0200 Subject: [PATCH] Updating master client message handling --- .../Master/Messages/MasterClientMessage.cs | 90 ++++++++++++++++--- 1 file changed, 79 insertions(+), 11 deletions(-) diff --git a/src/libnpsharp/Master/Messages/MasterClientMessage.cs b/src/libnpsharp/Master/Messages/MasterClientMessage.cs index 0e972ac..0da582b 100644 --- a/src/libnpsharp/Master/Messages/MasterClientMessage.cs +++ b/src/libnpsharp/Master/Messages/MasterClientMessage.cs @@ -1,17 +1,92 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; using System.Net.Sockets; using System.Reflection; using System.Text; +using log4net; namespace NPSharp.Master.Messages { public abstract class MasterClientMessage { + private static readonly ILog Log; + private byte[] _header = {0xFF, 0xFF, 0xFF, 0xFF}; + + static MasterClientMessage() + { + Log = LogManager.GetLogger(typeof (MasterClientMessage)); + } + protected List Properties { get; set; } - + + public virtual byte[] Header + { + get { return _header; } + protected set { _header = value; } + } + + internal string Name + { + get { return GetType().GetCustomAttribute().Name; } + } + internal MasterClientMessage Deserialize(Socket sock) { - // TODO + while (sock.Connected && !sock.Poll(2000, SelectMode.SelectRead)) + { + } + + if (!sock.Connected) + return null; + + try + { + var buffer = new byte[1400]; // max packet size = 1400 bytes in dpmaster + var length = sock.Receive(buffer); + + if (length == 0) + { + Log.Debug("Received 0 bytes"); + return null; + } + if (length < 4) + { + Log.ErrorFormat("Received incomplete 4-byte header (received {0} bytes instead)", length); + throw new ProtocolViolationException("Received incomplete header"); + } + + var header = buffer.Take(4).ToArray(); + var command = Encoding.ASCII.GetString(buffer, 4, length - 4).Trim(); + var commandSplit = command.Split(new[] {'\t', '\r', '\n', '\0', ' '}, + StringSplitOptions.RemoveEmptyEntries); + + var commandName = commandSplit[0]; + var commandArguments = commandSplit.Skip(1).ToArray(); + + // Search for a message class which fits to the commandName + var message = + (MasterClientMessage) Activator.CreateInstance(Assembly.GetExecutingAssembly() + .GetTypes() + .Single( + t => + t.IsSubclassOf(typeof (MasterClientMessage)) && + t.GetCustomAttribute() + .Name.Equals(commandName, StringComparison.OrdinalIgnoreCase))); + + // Call the individual deserialize method + message.Deserialize(commandArguments); + message.Header = header; + + return message; + } + catch (SocketException) + { + if (sock.Connected) + throw; + return null; + } } internal byte[] SerializeInternal() @@ -28,13 +103,6 @@ namespace NPSharp.Master.Messages return Name; } - public virtual byte[] Header { get { return new byte[] {0xFF, 0xFF, 0xFF, 0xFF}; } } - - internal string Name - { - get { return GetType().GetCustomAttribute().Name; } - } - protected abstract void Deserialize(string[] arguments); } -} +} \ No newline at end of file