public static byte[] ProcessSlaveFunction(ModbusTCPFrame frame) { DataModel dataModel; if (ModbusTCP.Slaves.Any(s => s.Key == frame.UnitIdentifier)) { dataModel = ModbusTCP.Slaves.FirstOrDefault(s => s.Key == frame.UnitIdentifier).Value; } else { dataModel = DataModel.Create(frame.UnitIdentifier); ModbusTCP.Slaves.Add(frame.UnitIdentifier, dataModel); } switch (frame.FunctionCode) { case FunctionCode.ReadCoils: return(dataModel.ReadCoils(frame.Data)); case FunctionCode.ReadDiscreteInputs: return(dataModel.ReadDiscreteInputs(frame.Data)); case FunctionCode.WriteSingleCoil: return(dataModel.WriteSingleCoil(frame.Data)); case FunctionCode.WriteMultipleCoils: return(dataModel.WriteMultipleCoils(frame.Data)); } return(new byte[0]); }
public void Start() { try { _server.Start(); // Buffer for reading data var bytes = new byte[1024]; string data = null; while (true) { Console.Write("Waiting for a connection... "); var client = _server.AcceptTcpClient(); Console.WriteLine("Connected!"); // Get a stream object for reading and writing var stream = client.GetStream(); // Loop to receive all the data sent by the client. while ((stream.Read(bytes, 0, bytes.Length)) != 0) { //Console.WriteLine("Received: {0}", Formatter.ByteArrayToString(bytes)); var frame = new ModbusTCPFrame(bytes); #if DEBUG Console.WriteLine("Transaction identifier: {0}", frame.TransactionIdentifier); Console.WriteLine("Protocol identifier: {0}", frame.ProtocolIdentifier); Console.WriteLine("Length field: {0}", frame.LengthField); Console.WriteLine("Unit identifier: {0}", frame.UnitIdentifier); Console.WriteLine("Function code: {0}", frame.FunctionCode.GetDescription()); Console.WriteLine("Data: {0}", Formatter.ByteArrayToString(frame.Data)); #endif byte[] returnData = FunctionMapping.ProcessSlaveFunction(frame); byte transActIdb0 = (byte)frame.TransactionIdentifier, transActIdb1 = (byte)(frame.TransactionIdentifier >> 8); byte unitId = (byte)frame.UnitIdentifier; byte function = (byte)frame.FunctionCode; byte dataLenth = (byte)(returnData.Length + 2); byte[] header = new byte[] { transActIdb1, transActIdb0, 0x00, 0x00, 0x00, dataLenth, unitId, function }; byte[] msg = _combine(header, returnData); // Send back a response. stream.Write(msg, 0, msg.Length); #if DEBUG Console.WriteLine("Sent: {0}", Formatter.ByteArrayToString(msg)); #endif } // Shutdown and end connection client.Close(); } } catch (Exception e) { Console.WriteLine(e); } finally { // Stop listening for new clients. _server.Stop(); } }