在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例Windows系统编程 → ModbusTcpMasterPro和ModbusTcpSlavePro实例源码

ModbusTcpMasterPro和ModbusTcpSlavePro实例源码

Windows系统编程

下载此实例
  • 开发语言:C#
  • 实例大小:2.92M
  • 下载次数:101
  • 浏览次数:362
  • 发布时间:2019-12-20
  • 实例类别:Windows系统编程
  • 发 布 人:dengshengbao
  • 文件格式:.zip
  • 所需积分:2
 相关标签: Modbus stc tcp

实例介绍

【实例简介】用于modbusTcp测试或dll,调用

【实例截图】

from clipboard


from clipboard


【核心代码】using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Timers;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;//序列化和反序列化


namespace Modbus
{
    /// <summary>
    /// ModbusTcp主站
    /// </summary>
    // modbustcp与串口类似,tcp端口是502,没有CRC校验,增加一个报文头固定码00 00 00 00,数据长度:高字节 低字节
    //(数据位:1-2) 定义我是谁(Transaction Identifier),协议给了我2byte空间定义我是谁,我代号就是00 00
    //(数据位:3-4)定义协议号,协议给了我2byte空间定义协议号(协议号就是00 00,表示这是MODBUS 协议)
    [Serializable]//对象可序列化标识
    public class ModbusTcpMaster
    {
        /// <summary>
        /// Modbus服务器IP地址
        /// </summary>
        public string IP;
        /// <summary>
        ///Modbus服务器端口号502
        /// </summary>
        public int Port;
        /// <summary>
        /// Modbus从站地址
        /// </summary>
        public byte Addr;
        /// <summary>
        /// 4.X只读寄存器地址0-65535
        /// </summary>
        public Int16[] ModbusD = new Int16[65535];
        private Int16[] ModbusDWriteR = new Int16[65535];//记忆寄存器,用于判断数据是否发生变化
        /// <summary>
        /// 采集频率
        /// </summary>
        public int ReadCycle;
        /// <summary>
        /// 只读开始地址
        /// </summary>
        public int ReadStartAddr;
        /// <summary>
        /// 只读寄存器数量
        /// </summary>
        public int ReadCount;
        /// <summary>
        /// 只写起始地址
        /// </summary>
        public int WriteStartAddr;
        /// <summary>
        /// 只写结束地址
        /// </summary>
        public int WriteEndAddr;
        /// <summary>
        /// 一次读写最大寄存器个数
        /// </summary>
        public int MaxReadWriteCount;
        /// <summary>
        ///  通讯错误
        /// </summary>
        public bool ComError;
        /// <summary>
        /// 是否记录通讯信息
        /// </summary>
        public bool IsComLog;
        private FileOpration ObjFileOpration = new FileOpration();
        private string ComLogFileName;
        public int SendCount = 0;//发送计数
        public int ReceiveCount = 0;//接收计数

        public  Socket SocketClient;//Socket客户端
        public Thread ModbusThread;//定义一个线程
        public Thread ModbusReceiveThread;//定义一个接收数据线程
        public System.Timers.Timer SampleTimer;//定义一个采集定时器

        //构造方法
        public ModbusTcpMaster()
        {
            Port = 502;
            if (ReadCycle < 100) ReadCycle = 100;//最小采集周期100ms
            if (ReadStartAddr < 0) ReadStartAddr = 0;//起始地址从0开始
            if (ReadCount == 0) ReadCount = 1;//最小读取一个数据
            if (MaxReadWriteCount < 10) MaxReadWriteCount = 10;
            if (MaxReadWriteCount > 100) MaxReadWriteCount = 100;
            ComLogFileName = "ComLog.txt";  
        }

        private List<int> WriteRegisterList = new List<int>();

        List<byte[]> SendDataList = new List<byte[]>();
        int ErrorCount = 0;//通读出错计数
        bool SendLable = false;//发送标志
        int SendCountR = 0;
        bool ReceiveLable = false;//接收标志
        private void ModbusThreadMethod()//线程方法,处理发送接收逻辑
        {
            while (true)
            {
                Thread.Sleep(1);
            }
        }
        private void GetSendDataList()
        {
            #region 生成只写寄存器集合
            int writeRegisterCount = WriteEndAddr - WriteStartAddr;
            if (writeRegisterCount > 0 && WriteStartAddr > (ReadStartAddr ReadCount))
            {
                for (int i = 0; i < writeRegisterCount; i )
                {
                    if (ModbusD[WriteStartAddr i] != ModbusDWriteR[WriteStartAddr i])//只写数据发生了变化
                    {
                        if (WriteRegisterList.Contains(WriteStartAddr i) == false) WriteRegisterList.Add(WriteStartAddr i);//把地址添加到集合
                        ModbusDWriteR[WriteStartAddr i] = ModbusD[WriteStartAddr i];
                    }
                }
            }
            #endregion
            byte cmd;
            #region 写指令
            if (WriteRegisterList.Count >= 1 && ReadStartAddr >= 0 && WriteStartAddr > (ReadStartAddr ReadCount) && ReadCycle >= 100)
            {
                //通过需要写入的寄存器集合,得到指令所需的起始地址和数量
                List<StartAddrCount> writeList = GetWriteStartAddrCount(WriteRegisterList);

                for (int i = 0; i < writeList.Count; i )
                {

                    byte[] sendData = WriteRigsterCmd16TCP(ModbusD, writeList[i].StartAddr, writeList[i].RegisterCount, out cmd);
                    //指令一致,起始地址一致时,说明指令已有
                    if (SendDataList.Count > 0)
                    {
                        if (SendDataList.Exists(t => (t[7] == 0x10) && ((t[8] * 255 t[9]) == writeList[i].StartAddr)) == false)
                            SendDataList.Add(sendData);
                    }
                    else
                    {
                        SendDataList.Add(sendData);
                    }
                }
            }
            #endregion
            #region 读指令
            if (ReadStartAddr >= 0 && WriteStartAddr > (ReadStartAddr ReadCount) && ReadCycle >= 100)
            {
                //如果读取的数据个数大于50个则分多次读取
                int a = ReadCount / MaxReadWriteCount;//整除
                int b = ReadCount % MaxReadWriteCount;//余数
                for (int i = 0; i < a; i )
                {
                    byte[] sendData = ReadRegisterCmd03TCP(ReadStartAddr MaxReadWriteCount * i, MaxReadWriteCount, out cmd);
                    //指令一致,起始地址一致时,说明指令已有
                    if (SendDataList.Count > 0)
                    {
                        if (SendDataList.Exists(t => (t[7] == 0x03) && ((t[8] * 255 t[9]) == (ReadStartAddr MaxReadWriteCount * i))) == false)
                            SendDataList.Add(sendData);
                    }
                    else
                    {
                        SendDataList.Add(sendData);
                    }
                }
                if (b != 0)
                {
                    byte[] sendData = ReadRegisterCmd03TCP(ReadStartAddr MaxReadWriteCount * a, b, out cmd);
                    //指令一致,起始地址一致时,说明指令已有
                    if (SendDataList.Count > 0)
                    {
                        if (SendDataList.Exists(t => (t[7] == 0x03) && ((t[8] * 255 t[9]) == (ReadStartAddr MaxReadWriteCount * a))) == false)
                            SendDataList.Add(sendData);
                    }
                    else
                    {
                        SendDataList.Add(sendData);
                    }
                }
            }
            #endregion
        }
        private void SampleTimer_Elapsed(object sender, ElapsedEventArgs e)//定时器方法,只发送数据
        {
            #region 发送指令和接收数据处理
            SocketClient = AutoConnectTCPServer(SocketClient, IP, Port);//自动连接socket

            GetSendDataList();//生成发送指令队列

            if (SocketClient == null || (SocketClient != null && SocketClient.Connected == false)) ComError = true;

            if (SocketClient != null && SocketClient.Connected == true && SendDataList.Count>0)//服务器连接正常
            {
                try
                {
                    if (SendLable == true && ReceiveLable == true)//发送完成,等待接收
                    {
                        //接收到数据后解析
                        if (SendCmdReturnValueTCP(receiveData, receiveRealLen, SendDataList[0]) == 1)
                        {
                            if (SendDataList.Count > 0)
                            {
                                SendDataList.Remove(SendDataList[0]);
                            }
                            SendCountR = SendCount;
                            ErrorCount = 0;
                            ComError = false;
                          
                        }
                        SendLable = false;
                        ReceiveLable = false;
                    }
                    #region Socket发送接收
                    if (SendCount != SendCountR)
                    {
                        ErrorCount ;//如果通讯错误重发
                        SendCountR = SendCount;
                    }
                    if (ErrorCount >= 5)//超过5次错误判断为通讯中断
                    {
                        if(SendDataList.Count>0)
                        SendDataList.Remove(SendDataList[0]);
                        ComError = true;
                        ErrorCount = 0;
                    }

                    if (SendDataList.Count > 0)
                    {
                        SendCount ;//发送计数
                        if (IsComLog == true)
                        {
                            string LogStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") " " SocketClient.LocalEndPoint.ToString() " 发送"
                                            " 次数:" SendCount.ToString() "通讯错误:" ErrorCount.ToString() 
                                            "队列总数:" SendDataList.Count.ToString() " " BitConverter.ToString(SendDataList[0]).Replace("-", " ");
                            ObjFileOpration.WriteLine(ComLogFileName, LogStr);//通讯记录
                        }

                        SocketClient.Send(SendDataList[0], SendDataList[0].Length, 0); //向服务器发送指令
                        SendLable = true;
                    }
                    #endregion
                }
                catch
                {

                }
            }
            #endregion
        }

        byte[] receiveData = new byte[1024];
        int receiveRealLen = -1;
        //独立线程只接收数据
        private void ReceiveServer()
        {
            while (true)
            {
                if (SocketClient != null && SocketClient.Connected == true)
                {
                    try
                    {
                        receiveRealLen = SocketClient.Receive(receiveData, receiveData.Length, 0); //同步从服务器接受消息
                        ReceiveCount ;
                        ReceiveLable = true;
                        if (IsComLog == true && receiveRealLen > 0)
                        {
                            string LogStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") " " SocketClient.RemoteEndPoint.ToString() " 接收"
                                            " 次数:" ReceiveCount.ToString() " " BitConverter.ToString(receiveData, 0, receiveRealLen).Replace("-", " ");
                            ObjFileOpration.WriteLine(ComLogFileName, LogStr);//通讯记录
                        }
                        if (receiveRealLen == 0)//接收到空消息,对方退出了
                        {
                            ObjFileOpration.WriteLine(ComLogFileName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") SocketClient.RemoteEndPoint.ToString() "退出");
                            SocketClient.Shutdown(SocketShutdown.Both);//关闭接收和发送
                            SocketClient.Close();//关闭Socket
                            return;//退出循环
                        }
                    }
                    catch
                    {

                    }
                }
                Thread.Sleep(1);
            }
        }
        /// <summary>
        /// 读取寄存器指令03
        /// </summary>
        /// <param name="startRegister">起始地址</param>
        /// <param name="count">寄存器数量,最多255</param>
        /// <param name="cmd">输出指令</param>
        /// <returns></returns>
        public byte[] ReadRegisterCmd03TCP(int startRegister, int count, out byte cmd)
        {
            byte[] sendBuffer = new byte[12];
            sendBuffer[0] = 0x00;//报文头固定码
            sendBuffer[1] = 0x00;//报文头固定码
            sendBuffer[2] = 0x00;//报文头固定码
            sendBuffer[3] = 0x00;//报文头固定码
            sendBuffer[4] = 0x00;//数据长度高字节
            sendBuffer[5] = 0x06;//数据长度低字节
            sendBuffer[6] = Addr;//地址
            sendBuffer[7] = 0x03;//指令
            sendBuffer[8] = (byte)(startRegister >> 8);//右移8位后强制转换为byte类型得到高8位
            sendBuffer[9] = (byte)startRegister;//直接转换为byte型去掉高8位得到低8位
            sendBuffer[10] = (byte)(count >> 8);//右移8位后强制转换为byte类型得到高8位
            sendBuffer[11] = (byte)count;//直接转换为byte型去掉高8位得到低8位
            cmd = sendBuffer[7];
            return sendBuffer;
        }
        /// <summary>
        /// 写单个寄存器指令06
        /// </summary>
        /// <param name="registerAddr">寄存器地址</param>
        /// <param name="cmd"></param>
        /// <returns></returns>
        public byte[] WriteRegisterCmd06TCP(Int16[] registerD,int registerAddr, out byte cmd)
        {
            byte[] sendBuffer = new byte[12];
            sendBuffer[0] = 0x00;//报文头固定码
            sendBuffer[1] = 0x00;//报文头固定码
            sendBuffer[2] = 0x00;//报文头固定码
            sendBuffer[3] = 0x00;//报文头固定码
            sendBuffer[4] = 0x00;//数据长度高字节
            sendBuffer[5] = 0x06;//数据长度低字节
            sendBuffer[6] = Addr;//地址
            sendBuffer[7] = 0x06;//指令
            sendBuffer[8] = (byte)(registerAddr >> 8);//右移8位后强制转换为byte类型得到寄存器地址高8位
            sendBuffer[9] = (byte)registerAddr;//直接转换为byte型去掉高8位得到寄存器地址低8位
            sendBuffer[10] = (byte)(registerD[registerAddr] >> 8);//右移8位后强制转换为byte类型得到寄存器值高8位
            sendBuffer[11] = (byte)registerD[registerAddr];//直接转换为byte型去掉高8位得到寄存器值低8位
            cmd = sendBuffer[7];
            return sendBuffer;
        }
        /// <summary>
        /// 写多个寄存器指令10
        /// </summary>
        /// <param name="startRegister"></param>
        /// <param name="count"></param>
        /// <param name="cmd"></param>
        /// <returns></returns>
        public byte[] WriteRigsterCmd16TCP(Int16[] registerD, int startRegister, int count, out byte cmd)
        {
            List<byte> sendBuffer = new List<byte>();

            sendBuffer.Add(0x00);//0报文头固定码
            sendBuffer.Add(0x00);//1报文头固定码
            sendBuffer.Add(0x00);//2报文头固定码
            sendBuffer.Add(0x00);//3报文头固定码
            sendBuffer.Add((byte)((2 * count 7) >> 8));//4数据长度高字节
            sendBuffer.Add((byte)(2 * count 7));//5数据长度低字节
            sendBuffer.Add(Addr);//6地址
            sendBuffer.Add(0x10);//7指令
            sendBuffer.Add((byte)(startRegister >> 8));//8右移8位后强制转换为byte类型得到,寄存器起始地址高8位
            sendBuffer.Add((byte)startRegister);//9直接转换为byte型去掉高8位得到,寄存器起始地址低8位
            sendBuffer.Add((byte)(count >> 8));//10右移8位后强制转换为byte类型得到,寄存器数量高8位
            sendBuffer.Add((byte)count);//11直接转换为byte型去掉高8位得到低8位
            sendBuffer.Add((byte)(2 * count));//12直接转换为byte型去掉高8位得到,寄存器数量低8位
            for (int i = 0; i < count; i )
            {
                sendBuffer.Add((byte)(registerD[startRegister i] >> 8));//右移8位后强制转换为byte类型得到高8位
                sendBuffer.Add((byte)registerD[startRegister i]);//直接转换为byte型去掉高8位得到低8位
            }
            cmd = sendBuffer[7];

            byte[] sendBF = sendBuffer.ToArray();//把集合复制到数组中

            return sendBF;
        }
        /// <summary>
        /// TCP发送指令后返回值处理程序
        /// </summary>
        /// <param name="receiveBuffer"></param>
        /// <param name="dataLength"></param>
        /// <param name="sendBuffer"></param>
        /// <returns></returns>
        public int SendCmdReturnValueTCP(byte[] receiveBuffer, int receiveDataLength, byte[] sendBuffer)
        {
            byte receiveCorrect = 0;
            if (Addr >= 0 && receiveDataLength >= 11) //接收数据够长
            {
                int byteTatolCount = 9 2 * (sendBuffer[10] * 256 sendBuffer[11]);//总接收字节数
                int startRegister = sendBuffer[8] * 256 sendBuffer[9];//起址寄存器,两个高低字节合并为一个字
                int registerCount = sendBuffer[10] * 256 sendBuffer[11];//寄存器数量

                #region 地址指令、接收字节正确,处理03读指令返回值
                if (receiveBuffer[6] == Addr && receiveBuffer[7] == 0x03 && receiveDataLength == byteTatolCount)
                {

                    if ((receiveBuffer[8] == registerCount * 2))//接收寄存器一致,分配数值
                    {
                        for (int i = 0; i < registerCount; i )
                        {
                            ModbusD[i startRegister] = (Int16)(receiveBuffer[2 * i 9] * 256 receiveBuffer[2 * i 10]);
                        }
                        receiveCorrect = 1;//接收正常
                    }
                    else receiveCorrect = 0;
                }
                #endregion
                #region 地址正确,处理06写单一寄存器指令返回值
                if (receiveBuffer[6] == Addr && receiveBuffer[7] == 0x06 && receiveDataLength == 12)
                {
                    int j = 0;
                    for (int i = 0; i < 12; i )
                    {
                        if (receiveBuffer[i] == sendBuffer[i])
                        {
                            j ;
                        }
                    }

                    if (j == 12) receiveCorrect = 1;//判断接收数据和发送数据完全一致
                    else receiveCorrect = 0;
                }
                #endregion
                #region 地址正确,16处理写多个寄存器指令返回值
                if (receiveBuffer[6] == Addr && receiveBuffer[7] == 0x10 && receiveDataLength == 12)
                {
                    int startRegisterR = receiveBuffer[8] * 256 receiveBuffer[9];//接收数据,起址寄存器,两个高低字节合并为一个字
                    int registerCountR = receiveBuffer[10] * 256 receiveBuffer[11];//接收数据,寄存器数量

                    if (startRegister == startRegisterR && registerCount == registerCountR)//接收寄存器,起始地址和寄存器数据
                    {
                        receiveCorrect = 1;//接收正常
                    }
                    else receiveCorrect = 0;
                }
                #endregion
            }
            return receiveCorrect;
        }
        /// <summary>
        /// socket自动重连
        /// </summary>
        /// <param name="_SocketClient"></param>
        /// <param name="strIP"></param>
        /// <param name="intPort"></param>
        /// <returns></returns>
        private Socket AutoConnectTCPServer(Socket _SocketClient, string strIP, int intPort)
        {
            if (_SocketClient == null)
            {
                Thread.Sleep(100);
                _SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                int SocketTimeOut = 100;
                _SocketClient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, SocketTimeOut);//设置这个socket的超时时间
                _SocketClient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, SocketTimeOut);//设置这个socket的超时时间
                try
                {
                    _SocketClient.Connect(new IPEndPoint(IPAddress.Parse(strIP), intPort)); //配置服务器IP与端口
                }
                catch
                {

                }
                return _SocketClient;
            }
            //断开自动重新创建连接
            if (_SocketClient != null && !_SocketClient.Connected)
            {
                _SocketClient.Close();
                //Thread.Sleep(1000);
                _SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                int SocketTimeOut = 100;
                _SocketClient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, SocketTimeOut);//设置这个socket的超时时间
                _SocketClient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, SocketTimeOut);//设置这个socket的超时时间
                try
                {
                    _SocketClient.Connect(new IPEndPoint(IPAddress.Parse(strIP), intPort)); //配置服务器IP与端口
                }
                catch
                {

                }
                return _SocketClient;

            }
            return _SocketClient;
        }
        /// <summary>
        /// 连接设备
        /// </summary>
        public void Connect()
        {
            SocketClient = AutoConnectTCPServer(SocketClient, IP, Port);//自动连接socket
            //启动线程
            ModbusThread = new Thread(ModbusThreadMethod);
            ModbusThread.IsBackground = true;
            //ModbusThread.Start();

            //启动定时器
            SampleTimer = new System.Timers.Timer(ReadCycle);
            SampleTimer.Elapsed = SampleTimer_Elapsed;
            SampleTimer.AutoReset = true;
            SampleTimer.Start();

            //启动数据接收线程
            ModbusReceiveThread = new Thread(ReceiveServer);
            ModbusReceiveThread.IsBackground = true;
            ModbusReceiveThread.Start();

            ComError = false;
            //通讯记录
            ObjFileOpration.WriteLine(ComLogFileName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") " 开始通讯 " IP);
        }

        /// <summary>
        /// 断开设备
        /// </summary>
        public void Disconnect()
        {
            if (ModbusThread != null) ModbusThread.Abort();//终止线程
            if (ModbusReceiveThread != null) ModbusReceiveThread.Abort();
            if (SampleTimer != null)
            {
                SampleTimer.Stop();
                SampleTimer.Close();
            }
            ComError = true;
            if (SocketClient != null)
            {
                SocketClient.Close();//关闭连接
            }
            //通讯记录
            ObjFileOpration.WriteLine(ComLogFileName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") " 断开通讯 " IP);
        }
        /// <summary>
        /// 获取寄存器开始地址和数量集合
        /// </summary>
        /// <param name="writeRegisterList"></param>
        /// <returns></returns>
        public List<StartAddrCount> GetWriteStartAddrCount(List<int> writeRegisterList)
        {
            writeRegisterList.Sort((x, y) => x.CompareTo(y));//集合排序,升序
            //writeRegisterList.Sort((x, y) => -x.CompareTo(y));//集合排序,降序

            List<StartAddrCount> writeList = new List<StartAddrCount>();
            int startAddr = writeRegisterList[0];
            int registerCount = 1;
            for (int i = 0; i < writeRegisterList.Count; i )
            {
                if (writeRegisterList.Count == 1)//只有一个寄存器时
                {
                    StartAddrCount objSAC = new StartAddrCount();
                    objSAC.RegisterCount = registerCount;
                    objSAC.StartAddr = startAddr;
                    writeList.Add(objSAC);
                    break;//跳出当前循环
                    //continue;//跳出本次循环,进入下一循环
                }
                else//有多个寄存器时
                {
                    if (i == 0)
                    {
                        registerCount = 1;
                        startAddr = writeRegisterList[i];
                    }
                    if (i > 0)
                    {
                        if (writeRegisterList[i] - writeRegisterList[i - 1] == 1)//判断寄存器是否连续
                        {
                            registerCount ;
                        }
                        else
                        {
                            //不连续增加新的集合
                            StartAddrCount objSAC = new StartAddrCount();
                            objSAC.StartAddr = startAddr;
                            objSAC.RegisterCount = registerCount;
                            writeList.Add(objSAC);
                            registerCount = 1;
                            startAddr = writeRegisterList[i];
                        }
                    }
                    if (i == (writeRegisterList.Count - 1))//到最后一个寄存器
                    {
                        StartAddrCount objSAC = new StartAddrCount();
                        objSAC.StartAddr = startAddr;
                        objSAC.RegisterCount = registerCount;
                        writeList.Add(objSAC);
                    }
                }
            }
            return writeList;
        }
        public void SaveModbusD()
        {
            try
            {
                //1.创建文件流
                FileStream fs = new FileStream("ModbusRegister.obj", FileMode.Create);
                //2.创建二进制格式化器
                BinaryFormatter formatter = new BinaryFormatter();
                //3.调用序列化方法
                formatter.Serialize(fs, ModbusD);
                //4.关闭文件流
                fs.Close();
            }
            catch
            {

            }

        }
        public void GetModbusD()
        {
            try
            {
                //1.创建文件流
                FileStream fs = new FileStream("ModbusRegister.obj", FileMode.Open);
                //2.创建二进制格式化器
                BinaryFormatter formatter = new BinaryFormatter();
                //3.调用反序列化方法
                ModbusD = (Int16[])formatter.Deserialize(fs);
                //4.关闭文件流
                fs.Close();
            }
            catch
            {

            }
        }
    }
}


标签: Modbus stc tcp

实例下载地址

ModbusTcpMasterPro和ModbusTcpSlavePro实例源码

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警