Example #1
0
 public void Run()
 {
     try
     {
         ServiceLog.Info(string.Format("正在建立 Modbus TCP 数据采集连接[{0} {1}:{2}]", ServerID, server_ip, server_port));
         clientSocket = ConnectToServer();
         ServiceLog.Info(string.Format("建立 Modbus TCP 数据采集连接[{0} {1}:{2}]成功...", ServerID, server_ip, server_port));
         HostContainer.AddModbusTcpClientHost(this);
     }
     catch (Exception ex)
     {
         ServiceLog.Error(string.Format("建立 Modbus TCP 数据采集连接[{0} {1}:{2}]发生错误:{3}", ServerID, server_ip, server_port, ex.Message));
         return;
     }
 }
Example #2
0
        private void StartModbusTcpClients()
        {
            try
            {
                string serversConfig = System.Configuration.ConfigurationManager.AppSettings["modbustcp"];
                if (serversConfig.Trim() == string.Empty)
                {
                    return;
                }
                string sWaitTime = System.Configuration.ConfigurationManager.AppSettings["interval"];
                uint   waitTime;
                if (!uint.TryParse(sWaitTime, out waitTime))
                {
                    waitTime = 500;
                }

                string sRetryTimes = System.Configuration.ConfigurationManager.AppSettings["retrytimes"];
                int    retryTimes;
                if (!int.TryParse(sRetryTimes, out retryTimes) || retryTimes < 0)
                {
                    retryTimes = 3;
                }

                JavaScriptSerializer    jss           = new JavaScriptSerializer();
                List <DataServerConfig> serverCfgList = jss.Deserialize <List <DataServerConfig> >(serversConfig);
                foreach (DataServerConfig serverCfg in serverCfgList)
                {
                    Thread.Sleep(1000);
                    if (serverCfg.ServerID.Trim() == string.Empty)
                    {
                        ServiceLog.Warn(string.Format("Modbus TCP 服务器标识符[{0}]无效", serverCfg.ServerID));
                        continue;
                    }
                    IPAddress ip;
                    if (!IPAddress.TryParse(serverCfg.IP, out ip))
                    {
                        IPAddress[] ips = Dns.GetHostAddresses(serverCfg.IP);
                        if (ips.Length == 0)
                        {
                            ServiceLog.Warn(string.Format("Modbus TCP 服务器IP地址[{0}]无效", serverCfg.IP));
                            continue;
                        }
                        else
                        {
                            foreach (IPAddress tempip in ips)
                            {
                                if (!tempip.IsIPv6LinkLocal && !tempip.IsIPv6Multicast && !tempip.IsIPv6SiteLocal)
                                {
                                    ip = tempip;
                                    break;
                                }
                            }

                            if (ip == null)
                            {
                                ServiceLog.Warn(string.Format("Modbus TCP 服务器IP地址[{0}]无效", serverCfg.IP));
                                continue;
                            }
                        }
                        //ServiceLog.LogServiceMessage(string.Format("Modbus TCP 服务器IP地址[{0}]无效", serverCfg.IP));
                        //continue;
                    }

                    ushort port;
                    if (!ushort.TryParse(serverCfg.Port, out port))
                    {
                        ServiceLog.Warn(string.Format("Modbus TCP 服务器端口[{0}]无效", serverCfg.Port));
                        continue;
                    }

                    byte devAddr;
                    if (!byte.TryParse(serverCfg.DevAddr, out devAddr))
                    {
                        devAddr = 1;
                    }

                    try
                    {
                        ModbusTcpClientHost mbTcpClientHost = new ModbusTcpClientHost(serverCfg.ServerID,
                                                                                      ip, port, devAddr, waitTime, retryTimes);
                        Thread thread = new Thread(new ThreadStart(mbTcpClientHost.Run));
                        thread.IsBackground = true;
                        thread.Start();
                    }
                    catch (Exception ex)
                    {
                        ServiceLog.Error(string.Format("启动 Modbus TCP 数据采集服务[{0} {1}:{2}]线程时发生错误:{3}", serverCfg.ServerID, serverCfg.IP, serverCfg.Port, ex.Message));
                    }
                }
            }
            catch (Exception ex)
            {
                ServiceLog.Warn(string.Format("获取 Modbus TCP 数据采集服务配置时发生错误:{0}", ex.Message));
            }
        }
Example #3
0
        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;
                }
            }
        }
Example #4
0
        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;
                }
            }
        }
Example #5
0
        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);
        }