DotNetty 实现 Modbus TCP 系列 (四) Client & Server

 本文已收录至:开源 DotNetty 实现的 Modbus TCP/IP 协议

Client

public class ModbusClient {     public string Ip { get; }     public int Port { get; }     public short UnitIdentifier { get; }     public IChannel Channel { get; private set; }      private MultithreadEventLoopGroup group;     private ConnectionState connectionState;     private ushort transactionIdentifier;     private readonly string handlerName = "response";      public ModbusClient(short unitIdentifier, string ip, int port = 502)     {         Ip = ip;         Port = port;         UnitIdentifier = unitIdentifier;          connectionState = ConnectionState.NotConnected;     }      public async Task Connect()     {         group = new MultithreadEventLoopGroup();          try         {             var bootstrap = new Bootstrap();             bootstrap                 .Group(group)                 .Channel<TcpSocketChannel>()                 .Option(ChannelOption.TcpNodelay, true)                 .Handler(new ActionChannelInitializer<ISocketChannel>(channel =>                 {                     IChannelPipeline pipeline = channel.Pipeline;                      pipeline.AddLast("encoder", new ModbusEncoder());                     pipeline.AddLast("decoder", new ModbusDecoder(false));                      pipeline.AddLast(handlerName, new ModbusResponseHandler());                 }));              connectionState = ConnectionState.Pending;              Channel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(Ip), Port));              connectionState = ConnectionState.Connected;         }         catch (Exception exception)         {             throw exception;         }     }      public async Task Close()     {         if (ConnectionState.Connected == connectionState)         {             try             {                 await Channel.CloseAsync();             }             finally             {                 await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));                  connectionState = ConnectionState.NotConnected;             }         }     }      public ushort CallModbusFunction(ModbusFunction function)     {         if (ConnectionState.Connected != connectionState || Channel == null)         {             throw new Exception("Not connected!");         }          SetTransactionIdentifier();          ModbusHeader header = new ModbusHeader(transactionIdentifier, UnitIdentifier);         ModbusFrame frame = new ModbusFrame(header, function);         Channel.WriteAndFlushAsync(frame);          return transactionIdentifier;     }      public T CallModbusFunctionSync<T>(ModbusFunction function) where T : ModbusFunction     {         var transactionIdentifier = CallModbusFunction(function);          var handler = (ModbusResponseHandler)Channel.Pipeline.Get(handlerName);         if (handler == null)         {             throw new Exception("Not connected!");         }          return (T)handler.GetResponse(transactionIdentifier).Function;     }      private void SetTransactionIdentifier()     {         if (transactionIdentifier < ushort.MaxValue)         {             transactionIdentifier++;         }         else         {             transactionIdentifier = 1;         }     }      public ushort ReadHoldingRegistersAsync(ushort startingAddress, ushort quantity)     {         var function = new ReadHoldingRegistersRequest(startingAddress, quantity);         return CallModbusFunction(function);     }      public ReadHoldingRegistersResponse ReadHoldingRegisters(ushort startingAddress, ushort quantity)     {         var function = new ReadHoldingRegistersRequest(startingAddress, quantity);         return CallModbusFunctionSync<ReadHoldingRegistersResponse>(function);     } }    public enum ConnectionState {     NotConnected = 0,     Connected = 1,     Pending = 2, }

(文中代码仅添加了 0x03 的方法)

在 Client 中封装了 Modbus 请求方法,对同一个功能同时有同步方法(ReadHoldingRegistersAsync)和异步方法(ReadHoldingRegisters)。同步方法仅返回 TransactionIdentifier(传输标识),异步方法返回响应结果。

ModbusResponseHandler 修改为:


                        
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信