public MBMessage(MBMessage request) { //this.result = result; this.TID = request.TID; this.PID = request.PID; this.UID = request.UID; this.Length = request.Length; this.FC = request.FC; this._body = new byte[request._body.Length]; Array.Copy(request._body, this._body, request._body.Length); }
public void TestMBMessage() { byte[] bs = ValueHelper.StrToToHexByte("00 86 00 00 00 06 01 01 01 01 00 02"); MBMessage mb = new MBMessage(bs); Assert.AreEqual(0x86, mb.TID); Assert.AreEqual(0, mb.PID); Assert.AreEqual(6, mb.Length); Assert.AreEqual(1, mb.UID); Assert.AreEqual(1, mb.FC); Assert.AreEqual(0x101, mb.GetWord(0)); Assert.AreEqual(0x2, mb.GetByte(3)); Assert.AreEqual(0x2, mb.GetWord(2)); }
// 异步发送应答. public void ASend(MBMessage resp) { if (resp != null) { byte[] buff = resp.encode(); if (this._socket != null) { Ack++; Sent += buff.Length; this._socket.Send(buff); } } }
public MBMessage DealRequest(MBConnect c, MBMessage req) { MBMessage resp; if (req.FC == 0x01) { resp = AckReadCoil(req); } else if ( req.FC == 0x05) { resp = AckWriteCoil(req); } else { resp = new MBMessage(req); resp.FC = (byte)(0x80 | req.FC); resp.SetBody(new byte[] { MBException.E01_ILLEGAL_FUNCTION }); } return resp; }
private MBMessage AckReadCoil(MBMessage req) { MBMessage resp = new MBMessage(req); /** * req: * Byte 1-2:Reference number * Byte 3-4:Bit count (1-2000) * resp: * Response * Byte 1: Byte count of response (B=(bit count+7)/8) * Byte 2-(B+1):Bit values (least significant bit is first coil!)" */ ushort refNum = req.GetWord(0); ushort bitCount = req.GetWord(2); if (_cms.IsValidRegAddress((byte)refNum)) { byte[] byteValues = _cms.MB_ReadCoils(refNum, bitCount); // 写入. var bcnt = byteValues.Length; resp.SetBodySize((ushort)(bcnt + 1)); resp.SetByte(0, (byte)bcnt); for (byte i = 0; i < bcnt; i++) { resp.SetByte(i + 1, byteValues[i]); } } else { // Error Response. // Byte 0:FC = 81 (hex) // Byte 1:exception code = 01 or 02 resp.FC = 0x82; resp.SetBody(new byte[] { MBException.E02_ILLEGAL_DATA_ADDRESS }); } return resp; }
private MBMessage SendRequest(MBMessage req) { try { SocketError err; byte[] buff = req.encode(); //log.DebugFormat("> {0:##}", ValueHelper.BytesToHexStr(buff)); byte[] ack = _client.SSend(req.encode(), out err); //log.DebugFormat("< {0:##}, err={1}", ValueHelper.BytesToHexStr(ack), err); if (SocketError.Success != err) { log.ErrorFormat("异常: {0}", err); } MBMessage resp = new MBMessage(ack); if (resp.FC > 0x80) { byte ec = resp.GetByte(0); log.ErrorFormat("Modbus 异常: {0}-{1} ", ec, MBException.NameOf(ec)); } return resp; } catch (Exception) { return null; } }
MBMessage NewWriteCoil(ushort addr, bool onOff) { MBMessage req = new MBMessage(); req.TID = 0xFF; req.UID = 0x01; req.PID = 0; req.FC = 0x05; req.SetBodySize(4); req.SetWord(0, addr); // 单樘门开门控制信号 - 读/写 0x11 req.SetByte(2, onOff ? (byte)0xFF : (byte)0x00); // 读取16*6个字节 req.SetByte(3, 0x00); return req; }
// 扫描 private void buttonScan_Click(object sender, EventArgs e) { if (_client == null) return; MBMessage req = new MBMessage(); req.TID = 0xFF; req.UID = 0x01; req.PID = 0; req.FC = 0x01; req.SetBodySize(4); req.SetWord(0, 0); // x: 0x0000 req.SetWord(2, 53 * 16); // 全部读取. MBMessage resp = SendRequest(req); int DOF = 1; if (resp == null) return; int zcnt = 6; int scnt = 7; //状态列: action,so,sc,err,lcb,green,red int regStart = 0x0B; int reg; int cs = ViewColumns.ACTION; for (int c = 0; c < scnt; c++) { // log.DebugFormat("state {0}", c); for (int z = 0; z < zcnt; z++) { reg = regStart + zcnt * c + z; // z=0: 11, 11+ 6*1, // log.DebugFormat("{0}", reg); byte b1 = resp.GetByte(reg * 2 + DOF); // Z0, 动作, 0-7 号门 byte b2 = resp.GetByte(reg * 2 + 1 + DOF); // Z0, 动作, 8-11号门 UpdateDoorState(z, c + cs, b1, 0, 8); UpdateDoorState(z, c + cs, b1, 8, 4); } } }
public void DoWork() { Socket myClientSocket = _client.Socket; byte[] result = new byte[1024]; while (_running) { // Is Timeout. try { if (myClientSocket.Poll(-1, SelectMode.SelectRead)) { //通过clientSocket接收数据 int aNumber = myClientSocket.Available; if (aNumber > 0) { int receiveNumber = myClientSocket.Receive(result); Log.InfoFormat("接收消息: {0}, len={1}, buff={2}", myClientSocket.RemoteEndPoint.ToString(), receiveNumber, ValueHelper.BytesToHexStr(result, receiveNumber)); MBMessage req = new MBMessage(result); if (req != null) { _client.Req++; _client.Recv += aNumber; ushort funCode = req.FC; Log.InfoFormat("消息: F={0:D2}, Unit=0x{1:X00}, len={2:D2}", req.FC, req.UID, req.Length); MBMessage resp = null; if (OnMsgDealed != null) { resp = OnMsgDealed.Invoke(_client, req); } else { Log.ErrorFormat("No delegate defined"); } if (resp != null) { _client.ASend(resp);// myClientSocket.Send(resp.encode()); } else { Log.ErrorFormat("Null resp, ack default."); } } else { Log.ErrorFormat("Invalid request."); } } } else { // 不可读. Log.InfoFormat("Clientk {0} broken.", _client.IP); _server.CloseClient(_client); break; } if (myClientSocket.Poll(20, SelectMode.SelectError)) { // Error Log.InfoFormat("Clientk {0} ERROR.", _client.IP); _server.CloseClient(_client); break; } } catch (Exception ex) { Log.Error(ex); _server.CloseClient(_client); break; } Thread.Sleep(10); } Log.InfoFormat("Client {0} exit.", _client.IP); }
private MBMessage _OnMsgDealed(MBConnect c, MBMessage req) { MBMessage resp = null; if (OnMsgDealed != null) { resp = OnMsgDealed.Invoke(c, req); } return resp; }
private MBMessage OnMBClientRequest(MBConnect c, MBMessage req) { UpdateMBClient(c, ClientAction.UPDATE); if (_handler != null) { return _handler.DealRequest(c, req); } return null; }
/* WriteCoil REQ: Byte 0:FC = 05 Byte 1-2: Reference number Byte 3:= FF to turn coil ON, =00 to turn coil OFF Byte 4:= 00 Resp: Byte 1-2:Reference number Byte 3:= FF to turn coil ON, =00 to turn coil OFF (echoed) Byte 4:= 00" */ private MBMessage AckWriteCoil(MBMessage req) { MBMessage resp = new MBMessage(req); // copy header ushort refNum = req.GetWord(0); // byte val = req.GetByte(2); byte result = _cms.MB_WriteCoil(refNum, val); // exception if (MBException.MB_SUCCESS == result) { // OK, return resp } else { // ERROR resp.FC = 0x85; resp.SetBody(new byte[] { result }); } return resp; }