public string RequestModbusRTUData(byte devAddr, byte funcCode, ushort startAddr, ushort regCount, out string respCRC) { string mbRtuData = string.Empty; respCRC = string.Empty; byte[] temp = new byte[6]; temp[0] = devAddr; temp[1] = funcCode; byte[] bStartAddr = BitConverter.GetBytes(startAddr); temp[2] = bStartAddr[1]; temp[3] = bStartAddr[0]; byte[] bRegCount = BitConverter.GetBytes(regCount); temp[4] = bRegCount[1]; temp[5] = bRegCount[0]; uint iCRC16 = ModbusCRC16(temp, temp.Length); byte[] bCrc16 = BitConverter.GetBytes(iCRC16); byte[] modbusRtuReq = new byte[8]; modbusRtuReq[0] = temp[0]; modbusRtuReq[1] = temp[1]; modbusRtuReq[2] = temp[2]; modbusRtuReq[3] = temp[3]; modbusRtuReq[4] = temp[4]; modbusRtuReq[5] = temp[5]; //CRC16 低位在前,高位在后 modbusRtuReq[6] = bCrc16[0]; modbusRtuReq[7] = bCrc16[1]; int retryTimes = 0; while (retryTimes <= this.retryTimes) { try { ServiceLog.Debug(string.Format("请求报文:{0}\r\n发送端:[{1} {2}:{3}]\r\n接收端:{4}", BitConverter.ToString(modbusRtuReq), ServerID, server_ip, server_port, clientSocketEndPointInfo)); clientSocket.Send(modbusRtuReq); } catch (Exception ex) { ServiceLog.Error(string.Format("数据采集服务[{0} {1}:{2}]发送请求到[{3}]时连接发生错误:{4}\r\n重试连接", ServerID, server_ip, server_port, clientSocketEndPointInfo, ex.Message)); if (retryTimes >= this.retryTimes) { throw new Exception(string.Format("数据采集服务[{0} {1}:{2}]发送请求到[{3}]时连接发生错误:{4}", ServerID, server_ip, server_port, clientSocketEndPointInfo, ex.Message)); } retryTimes++; ReconnectToServer(); continue; } byte[] modbusRtuResponse = new byte[5 + regCount * 2]; try { clientSocket.Receive(modbusRtuResponse, modbusRtuResponse.Length, SocketFlags.None); ServiceLog.Debug(string.Format("回应报文:{0}\r\n发送端:{1}\r\n接收端:[{2} {3}:{4}]", BitConverter.ToString(modbusRtuResponse), clientSocketEndPointInfo, ServerID, server_ip, server_port)); mbRtuData = BitConverter.ToString(modbusRtuResponse, 3, regCount * 2).Replace("-", string.Empty); respCRC = BitConverter.ToString(modbusRtuResponse, 3 + regCount * 2, 2).Replace("-", string.Empty); } catch (Exception ex) { ServiceLog.Error(string.Format("数据采集服务[{0} {1}:{2}]接收[{3}]回应时连接发生错误:{4}\r\n重试连接", ServerID, server_ip, server_port, clientSocketEndPointInfo, ex.Message)); if (retryTimes >= this.retryTimes) { throw new Exception(string.Format("数据采集服务[{0} {1}:{2}]接收[{3}]回应时连接发生错误:{4}", ServerID, server_ip, server_port, clientSocketEndPointInfo, ex.Message)); } retryTimes++; ReconnectToServer(); continue; } break; } /* * byte[] modbusRtuResponse = new byte[5 + regCount * 2]; * try * { * ServiceLog.Debug(string.Format("请求报文:{0}\r\n发送端:[{1} {2}:{3}]\r\n接收端:{4}", * BitConverter.ToString(modbusRtuReq), ServerID, server_ip, server_port, clientSocketEndPointInfo)); * * clientSocket.Send(modbusRtuReq); * clientSocket.Receive(modbusRtuResponse, modbusRtuResponse.Length, SocketFlags.None); * * ServiceLog.Debug(string.Format("回应报文:{0}\r\n发送端:{1}\r\n接收端:[{2} {3}:{4}]", * BitConverter.ToString(modbusRtuResponse), clientSocketEndPointInfo, ServerID, server_ip, server_port)); * * mbRtuData = BitConverter.ToString(modbusRtuResponse, 3, regCount * 2).Replace("-", string.Empty); * respCRC = BitConverter.ToString(modbusRtuResponse, 3 + regCount * 2, 2).Replace("-", string.Empty); * } * catch (Exception ex) * { * //可能客户端连接断开,重试一次 * ServiceLog.Error(string.Format("数据采集服务[{0} {1}:{2}]与[{3}]连接发生错误:{4}\r\n重试连接", * ServerID, server_ip, server_port, clientSocketEndPointInfo, ex.Message)); * if (clientSocket != null && clientSocket.Connected) * { * clientSocket.Disconnect(false); * } * clientSocket = null; * * try * { * * Thread.Sleep((int)waitTime); * ServiceLog.Debug(string.Format("请求报文:{0}\r\n发送端:[{1} {2}:{3}]\r\n接收端:{4}", * BitConverter.ToString(modbusRtuReq), ServerID, server_ip, server_port, clientSocketEndPointInfo)); * * clientSocket.Send(modbusRtuReq); * clientSocket.Receive(modbusRtuResponse, modbusRtuResponse.Length, SocketFlags.None); * * ServiceLog.Debug(string.Format("回应报文:{0}\r\n发送端:{1}\r\n接收端:[{2} {3}:{4}]", * BitConverter.ToString(modbusRtuResponse), clientSocketEndPointInfo, ServerID, server_ip, server_port)); * * * mbRtuData = BitConverter.ToString(modbusRtuResponse, 3, regCount * 2).Replace("-", string.Empty); * respCRC = BitConverter.ToString(modbusRtuResponse, 3 + regCount * 2, 2).Replace("-", string.Empty); * } * catch (Exception) * { * string errMsg = string.Format("数据采集服务[{0} {1}:{2}]与[{3}]连接发生错误:{4}", * ServerID, server_ip, server_port, clientSocketEndPointInfo, ex.Message); * ServiceLog.Error(errMsg); * if (clientSocket != null && clientSocket.Connected) * { * clientSocket.Disconnect(false); * } * clientSocket = null; * string exceptMsg = string.Format("数据采集服务与远程数据服务器连接发生错误:{0}", * ex.Message); * throw new Exception(errMsg); * } * * } */ return(mbRtuData); }
public void WriteModbusTCPData(string writeData) { var js = new System.Web.Script.Serialization.JavaScriptSerializer(); Dictionary <string, object> jarr = js.Deserialize <Dictionary <string, object> >(writeData); foreach (KeyValuePair <string, object> j in jarr) { ushort startAddr; if (!ushort.TryParse(j.Key, out startAddr)) { return; } ushort regCount; switch (j.Value.ToString().Length) { case 4: regCount = 1; break; case 8: regCount = 2; break; default: return; } byte[] inputValues16Byte = new byte[regCount * 2]; for (int i = 0; i < inputValues16Byte.Length; i++) { string sValue = j.Value.ToString().Substring(i * 2, 2); inputValues16Byte[i] = Convert.ToByte(sValue, 16); } /* * 00:传输标志Hi * 01:传输标志Lo * 02、03:协议标志 * 04、05:此位置以后字节数 * 06:单元标志 * 07:功能代码,0x10表示写多个寄存器 * 08、9:起始寄存器 * 10、11:寄存器数量 * 12:数据字节数 * 13~:数据 */ byte[] plc_send16 = new byte[13 + regCount * 2]; //标识符 ushort identifier = GetIdentifier(); byte[] bIdentifier = BitConverter.GetBytes(identifier); plc_send16[0] = bIdentifier[1]; plc_send16[1] = bIdentifier[0]; plc_send16[2] = 0; plc_send16[3] = 0; plc_send16[4] = 0; plc_send16[5] = (byte)(7 + regCount * 2); plc_send16[6] = this.DevAddr; plc_send16[7] = 16; byte[] bRegAddr16 = BitConverter.GetBytes(startAddr); plc_send16[8] = bRegAddr16[1]; plc_send16[9] = bRegAddr16[0]; byte[] bRegCount16 = BitConverter.GetBytes(regCount); plc_send16[10] = bRegCount16[1]; plc_send16[11] = bRegCount16[0]; byte byteCount = (byte)(regCount * 2); plc_send16[12] = byteCount; for (int i = 0; i < inputValues16Byte.Length; i++) { plc_send16[13 + i] = inputValues16Byte[i]; } for (int i = 0; i < plc_send16.Length; i++) { Console.WriteLine(plc_send16[i]); } /* * try * { * clientSocket.Send(plc_send16, plc_send16.Length, SocketFlags.None); * } * catch (SocketException se) * { * Console.WriteLine("发送消息失败:{0}", se.SocketErrorCode.ToString()); * break; * } */ int retryTimes = 0; while (retryTimes <= this.retryTimes) { try { ServiceLog.Debug(string.Format("正在写入数据到 Modbus TCP 服务器[{0} {1}:{2}]\r\n报文内容:{3}", ServerID, server_ip, server_port, BitConverter.ToString(plc_send16))); clientSocket.Send(plc_send16, plc_send16.Length, SocketFlags.None); } catch (Exception ex) { ServiceLog.Error(string.Format("写入数据到 Modbus TCP 服务器[{0} {1}:{2}]连接发生错误:{3}\r\n报文内容:{4}", ServerID, server_ip, server_port, ex.Message, BitConverter.ToString(plc_send16))); if (retryTimes >= this.retryTimes) { throw new CustomException(string.Format("写入数据到 Modbus TCP 服务器时发生错误:{0}", ex.Message), CustomExceptionType.CET_NETWORK_ERROR); } retryTimes++; ReconnectToServer(); continue; } byte[] recMsgByte16 = new byte[12]; int recLen16; try { //Thread.Sleep(5000); recLen16 = clientSocket.Receive(recMsgByte16, recMsgByte16.Length, SocketFlags.None); ServiceLog.Debug(string.Format("接收到 Modbus TCP 服务器[{0} {1}:{2}]数据\r\n报文内容:{3}", ServerID, server_ip, server_port, BitConverter.ToString(recMsgByte16))); string nullDataErrMsg = CheckIsNullData(recMsgByte16); if (nullDataErrMsg != string.Empty) { throw new CustomException(string.Format("接收到 Modbus TCP 服务器返回的错误:{0}", nullDataErrMsg), CustomExceptionType.CET_MB_NULL_DATA); } } catch (SocketException se) { ServiceLog.Debug(string.Format("接收消息失败:{0}", se.SocketErrorCode.ToString())); break; } //判断是否返回异常代码 CustomExceptionType cet; string errMsg = CheckExceptionCode(recMsgByte16, out cet); if (errMsg != string.Empty) { throw new CustomException(string.Format("接收到 Modbus TCP 服务器返回的错误:{0}", errMsg), cet); } break; } } }
public void WriteModbusTCPCoilStatus(string writeData) { var js = new System.Web.Script.Serialization.JavaScriptSerializer(); Dictionary <string, object> jarr = js.Deserialize <Dictionary <string, object> >(writeData); foreach (KeyValuePair <string, object> j in jarr) { ushort startAddr; if (!ushort.TryParse(j.Key, out startAddr)) { return; } ushort coilCount = 1; byte coilStatus; if (!byte.TryParse(j.Value.ToString(), out coilStatus) || (coilStatus != 0 && coilStatus != 1)) { return; } /* * 01:传输标志Hi * 02:传输标志Lo * 03、04:协议标志 * 05、06:此位置以后字节数 * 07:单元标志 * 08:功能代码,0x0F表示写多个线圈 * 09、10:起始线圈地址 * 11、12:线圈数量 * 13:数据字节数 * 14~:数据 */ byte[] plc_send15 = new byte[14]; //标识符 ushort identifier = GetIdentifier(); byte[] bIdentifier = BitConverter.GetBytes(identifier); plc_send15[0] = bIdentifier[1]; plc_send15[1] = bIdentifier[0]; plc_send15[2] = 0; plc_send15[3] = 0; ushort iLen15 = 8; byte[] bLen15 = BitConverter.GetBytes(iLen15); plc_send15[4] = bLen15[1]; plc_send15[5] = bLen15[0]; plc_send15[6] = this.DevAddr; plc_send15[7] = 15; byte[] bRegAddr15 = BitConverter.GetBytes(startAddr); plc_send15[8] = bRegAddr15[1]; plc_send15[9] = bRegAddr15[0]; byte[] bCoilCount15 = BitConverter.GetBytes(coilCount); plc_send15[10] = bCoilCount15[1]; plc_send15[11] = bCoilCount15[0]; byte byteCount15 = 1; plc_send15[12] = byteCount15; plc_send15[13] = coilStatus; int retryTimes = 0; while (retryTimes <= this.retryTimes) { try { ServiceLog.Debug(string.Format("正在写入数据到 Modbus TCP 服务器[{0} {1}:{2}]\r\n报文内容:{3}", ServerID, server_ip, server_port, BitConverter.ToString(plc_send15))); clientSocket.Send(plc_send15, plc_send15.Length, SocketFlags.None); } catch (Exception ex) { ServiceLog.Error(string.Format("写入数据到 Modbus TCP 服务器[{0} {1}:{2}]连接发生错误:{3}\r\n报文内容:{4}", ServerID, server_ip, server_port, ex.Message, BitConverter.ToString(plc_send15))); if (retryTimes >= this.retryTimes) { throw new CustomException(string.Format("写入数据到 Modbus TCP 服务器时发生错误:{0}", ex.Message), CustomExceptionType.CET_NETWORK_ERROR); } retryTimes++; ReconnectToServer(); continue; } byte[] recMsgByte15 = new byte[12]; int recLen15; try { //Thread.Sleep(5000); recLen15 = clientSocket.Receive(recMsgByte15, recMsgByte15.Length, SocketFlags.None); ServiceLog.Debug(string.Format("接收到 Modbus TCP 服务器[{0} {1}:{2}]数据\r\n报文内容:{3}", ServerID, server_ip, server_port, BitConverter.ToString(recMsgByte15))); string nullDataErrMsg = CheckIsNullData(recMsgByte15); if (nullDataErrMsg != string.Empty) { throw new CustomException(string.Format("接收到 Modbus TCP 服务器返回的错误:{0}", nullDataErrMsg), CustomExceptionType.CET_MB_NULL_DATA); } } catch (SocketException se) { ServiceLog.Debug(string.Format("接收消息失败:{0}", se.SocketErrorCode.ToString())); break; } //判断是否返回异常代码 CustomExceptionType exCode; string errMsg = CheckExceptionCode(recMsgByte15, out exCode); if (errMsg != string.Empty) { throw new CustomException(string.Format("接收到 Modbus TCP 服务器返回的错误:{0}", errMsg), exCode); } break; } } }
public string RequestModbusTcpCoilStatus(ushort startAddr, ushort coilCount, string returnFormat) { string mbTcpStatus = string.Empty; byte[] mbTcpSend = new byte[12]; //标识符 ushort identifier = GetIdentifier(); byte[] bIdentifier = BitConverter.GetBytes(identifier); mbTcpSend[0] = bIdentifier[1]; mbTcpSend[1] = bIdentifier[0]; //Modbus Tcp 协议 mbTcpSend[2] = 0; mbTcpSend[3] = 0; //请求报文长度 mbTcpSend[4] = 0; mbTcpSend[5] = 6; //设备地址 mbTcpSend[6] = this.DevAddr; //功能代码 mbTcpSend[7] = 1; //起始寄存器 byte[] bStartAddr = BitConverter.GetBytes(startAddr); mbTcpSend[8] = bStartAddr[1]; mbTcpSend[9] = bStartAddr[0]; //寄存器数量 byte[] bCoilCount = BitConverter.GetBytes(coilCount); mbTcpSend[10] = bCoilCount[1]; mbTcpSend[11] = bCoilCount[0]; byte iResultLen01 = (byte)(coilCount / 8); if (coilCount % 8 > 0) { iResultLen01++; } int retryTimes = 0; while (retryTimes <= this.retryTimes) { try { ServiceLog.Debug(string.Format("正在发送请求到 Modbus TCP 服务器[{0} {1}:{2}]\r\n请求报文内容:{3}", ServerID, server_ip, server_port, BitConverter.ToString(mbTcpSend))); clientSocket.Send(mbTcpSend, mbTcpSend.Length, SocketFlags.None); } catch (Exception ex) { ServiceLog.Error(string.Format("发送请求到 Modbus TCP 服务器[{0} {1}:{2}]连接发生错误:{3}\r\n请求报文内容:{4}", ServerID, server_ip, server_port, ex.Message, BitConverter.ToString(mbTcpSend))); if (retryTimes >= this.retryTimes) { throw new CustomException(string.Format("发送请求到 Modbus TCP 服务器时发生错误:{0}", ex.Message), CustomExceptionType.CET_NETWORK_ERROR); } retryTimes++; ReconnectToServer(); continue; } byte[] mbTcpRecv = new byte[9 + iResultLen01]; try { clientSocket.Receive(mbTcpRecv, mbTcpRecv.Length, SocketFlags.None); ServiceLog.Debug(string.Format("接收到 Modbus TCP 服务器[{0} {1}:{2}]回应\r\n回应报文内容:{3}", ServerID, server_ip, server_port, BitConverter.ToString(mbTcpRecv))); string nullDataErrMsg = CheckIsNullData(mbTcpRecv); if (nullDataErrMsg != string.Empty) { throw new CustomException(string.Format("接收到 Modbus TCP 服务器返回的错误:{0}", nullDataErrMsg), CustomExceptionType.CET_MB_NULL_DATA); } } catch (Exception ex) { ServiceLog.Error(string.Format("接收 Modbus TCP 服务器[{0} {1}:{2}]回应时发生错误:{3}", ServerID, server_ip, server_port, ex.Message)); if (retryTimes >= this.retryTimes) { throw new CustomException(string.Format("接收 Modbus TCP 服务器回应时发生错误:{0}", ex.Message), CustomExceptionType.CET_NETWORK_ERROR); } retryTimes++; ReconnectToServer(); continue; } //判断是否返回异常代码 CustomExceptionType cet; string errMsg = CheckExceptionCode(mbTcpRecv, out cet); if (errMsg != string.Empty) { throw new CustomException(string.Format("接收到 Modbus TCP 服务器返回的错误:{0}", errMsg), cet); } // mbTcpStatus = BitConverter.ToString(mbTcpRecv, 9, iResultLen01).Replace("-", string.Empty); break; } try { if (returnFormat.ToLower().Trim() == "json") { string statusArray = string.Empty; for (int i = 0; i < iResultLen01; i++) { string sByte = mbTcpStatus.Substring(i * 2, 2); byte bByte = Convert.ToByte(sByte, 16); string status = Convert.ToString(bByte, 2).PadLeft(8, '0'); statusArray = statusArray + getReverse(status); } string mbTcpStatusJson = string.Empty; for (int i = 0; i < coilCount; i++) { if (i == 0) { mbTcpStatusJson = string.Format("\"{0}\":\"{1}\"", startAddr + i, statusArray.Substring(i, 1)); } else { mbTcpStatusJson = string.Format("{0},\"{1}\":\"{2}\"", mbTcpStatusJson, startAddr + i, statusArray.Substring(i, 1)); } } mbTcpStatus = string.Format("{{{0}}}", mbTcpStatusJson); } } catch (Exception ex) { ServiceLog.Error(string.Format("转换 Modbus TCP 服务器[{0} {1}:{2}]回应数据\r\n{3}\r\n时发生错误:{4}", ServerID, server_ip, server_port, mbTcpStatus, ex.Message)); if (retryTimes >= this.retryTimes) { throw new CustomException(string.Format("转换 Modbus TCP 服务器回应数据时发生错误:{0}", ex.Message), CustomExceptionType.CET_Unknown); } } return(mbTcpStatus); }