MODBUS RTU/TCP通讯工具源码(不使用库文件)

MODBUS RTU/TCP通讯工具源码(不使用库文件)

MODBUS RTU/TCP协议及常用功能码详解
链接: https://blog.csdn.net/qq_43254236/article/details/118152650.
使用库文件的通讯工具看这里
链接: https://www.cnblogs.com/pandefu/p/10824331.html.

MODBUS RTU/TCP通讯工具源码

先看看软件界面
MODBUS RTU/TCP通讯工具界面

软件界面代码

namespace ModbusRtu
{
    partial class Form1
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.label1 = new System.Windows.Forms.Label();
            this.comboBox1 = new System.Windows.Forms.ComboBox();
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.gbRTU = new System.Windows.Forms.GroupBox();
            this.cmb_stopBits = new System.Windows.Forms.ComboBox();
            this.label6 = new System.Windows.Forms.Label();
            this.cmb_databBits = new System.Windows.Forms.ComboBox();
            this.label5 = new System.Windows.Forms.Label();
            this.cmb_parity = new System.Windows.Forms.ComboBox();
            this.button3 = new System.Windows.Forms.Button();
            this.label4 = new System.Windows.Forms.Label();
            this.cmb_baud = new System.Windows.Forms.ComboBox();
            this.label3 = new System.Windows.Forms.Label();
            this.cmb_portname = new System.Windows.Forms.ComboBox();
            this.label2 = new System.Windows.Forms.Label();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.checkBox2 = new System.Windows.Forms.CheckBox();
            this.button4 = new System.Windows.Forms.Button();
            this.checkBox1 = new System.Windows.Forms.CheckBox();
            this.txt_length = new System.Windows.Forms.TextBox();
            this.label8 = new System.Windows.Forms.Label();
            this.txt_startAddr1 = new System.Windows.Forms.TextBox();
            this.label7 = new System.Windows.Forms.Label();
            this.txt_slave1 = new System.Windows.Forms.TextBox();
            this.label11 = new System.Windows.Forms.Label();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.label13 = new System.Windows.Forms.Label();
            this.txt_data = new System.Windows.Forms.TextBox();
            this.label9 = new System.Windows.Forms.Label();
            this.txt_startAddr2 = new System.Windows.Forms.TextBox();
            this.label10 = new System.Windows.Forms.Label();
            this.txt_slave2 = new System.Windows.Forms.TextBox();
            this.label12 = new System.Windows.Forms.Label();
            this.richTextBox1 = new System.Windows.Forms.RichTextBox();
            this.cmb_DataFormat = new System.Windows.Forms.ComboBox();
            this.label15 = new System.Windows.Forms.Label();
            this.cmb_VarType = new System.Windows.Forms.ComboBox();
            this.label14 = new System.Windows.Forms.Label();
            this.port = new System.IO.Ports.SerialPort(this.components);
            this.groupBox4 = new System.Windows.Forms.GroupBox();
            this.gbTCP = new System.Windows.Forms.GroupBox();
            this.label16 = new System.Windows.Forms.Label();
            this.tbTCPIP = new System.Windows.Forms.TextBox();
            this.tbTCPPort = new System.Windows.Forms.TextBox();
            this.tbLocalPort = new System.Windows.Forms.TextBox();
            this.label17 = new System.Windows.Forms.Label();
            this.label18 = new System.Windows.Forms.Label();
            this.rbRTU = new System.Windows.Forms.RadioButton();
            this.rbTCP = new System.Windows.Forms.RadioButton();
            this.btnOpen = new System.Windows.Forms.Button();
            this.gbRTU.SuspendLayout();
            this.groupBox1.SuspendLayout();
            this.groupBox2.SuspendLayout();
            this.groupBox4.SuspendLayout();
            this.gbTCP.SuspendLayout();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(8, 29);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(41, 12);
            this.label1.TabIndex = 2;
            this.label1.Text = "功能码";
            // 
            // comboBox1
            // 
            this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.comboBox1.FormattingEnabled = true;
            this.comboBox1.Items.AddRange(new object[] {
            "01 Read Coils",
            "02 Read DisCrete Inputs",
            "03 Read Holding Registers",
            "04 Read Input Registers",
            "05 Write Single Coil",
            "06 Write Single Registers",
            "0F Write Multiple Coils",
            "10 Write Multiple Registers"});
            this.comboBox1.Location = new System.Drawing.Point(55, 26);
            this.comboBox1.Name = "comboBox1";
            this.comboBox1.Size = new System.Drawing.Size(177, 20);
            this.comboBox1.TabIndex = 1;
            this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
            // 
            // button1
            // 
            this.button1.Image = global::ModbusRtu.Properties.Resources.finger;
            this.button1.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.button1.Location = new System.Drawing.Point(561, 20);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(119, 28);
            this.button1.TabIndex = 4;
            this.button1.Text = "Read/Write ";
            this.button1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(697, 20);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(75, 28);
            this.button2.TabIndex = 9;
            this.button2.Text = "Clear";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // gbRTU
            // 
            this.gbRTU.Controls.Add(this.cmb_stopBits);
            this.gbRTU.Controls.Add(this.label6);
            this.gbRTU.Controls.Add(this.cmb_databBits);
            this.gbRTU.Controls.Add(this.label5);
            this.gbRTU.Controls.Add(this.cmb_parity);
            this.gbRTU.Controls.Add(this.button3);
            this.gbRTU.Controls.Add(this.label4);
            this.gbRTU.Controls.Add(this.cmb_baud);
            this.gbRTU.Controls.Add(this.label3);
            this.gbRTU.Controls.Add(this.cmb_portname);
            this.gbRTU.Controls.Add(this.label2);
            this.gbRTU.Location = new System.Drawing.Point(12, 100);
            this.gbRTU.Name = "gbRTU";
            this.gbRTU.Size = new System.Drawing.Size(777, 65);
            this.gbRTU.TabIndex = 10;
            this.gbRTU.TabStop = false;
            this.gbRTU.Text = "串口参数";
            // 
            // cmb_stopBits
            // 
            this.cmb_stopBits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cmb_stopBits.FormattingEnabled = true;
            this.cmb_stopBits.Items.AddRange(new object[] {
            "1",
            "2",
            "1.5"});
            this.cmb_stopBits.Location = new System.Drawing.Point(575, 22);
            this.cmb_stopBits.Name = "cmb_stopBits";
            this.cmb_stopBits.Size = new System.Drawing.Size(76, 20);
            this.cmb_stopBits.TabIndex = 32;
            // 
            // label6
            // 
            this.label6.AutoSize = true;
            this.label6.Location = new System.Drawing.Point(528, 25);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(41, 12);
            this.label6.TabIndex = 31;
            this.label6.Text = "停止位";
            // 
            // cmb_databBits
            // 
            this.cmb_databBits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cmb_databBits.FormattingEnabled = true;
            this.cmb_databBits.Items.AddRange(new object[] {
            "7",
            "8"});
            this.cmb_databBits.Location = new System.Drawing.Point(446, 22);
            this.cmb_databBits.Name = "cmb_databBits";
            this.cmb_databBits.Size = new System.Drawing.Size(76, 20);
            this.cmb_databBits.TabIndex = 30;
            // 
            // label5
            // 
            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(399, 25);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(41, 12);
            this.label5.TabIndex = 32;
            this.label5.Text = "数据位";
            // 
            // cmb_parity
            // 
            this.cmb_parity.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cmb_parity.FormattingEnabled = true;
            this.cmb_parity.Items.AddRange(new object[] {
            "奇",
            "偶",
            "无"});
            this.cmb_parity.Location = new System.Drawing.Point(317, 22);
            this.cmb_parity.Name = "cmb_parity";
            this.cmb_parity.Size = new System.Drawing.Size(76, 20);
            this.cmb_parity.TabIndex = 28;
            // 
            // button3
            // 
            this.button3.Location = new System.Drawing.Point(665, 20);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(106, 23);
            this.button3.TabIndex = 40;
            this.button3.Text = "打开串口";
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.button3_Click);
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(282, 25);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(29, 12);
            this.label4.TabIndex = 27;
            this.label4.Text = "校验";
            // 
            // cmb_baud
            // 
            this.cmb_baud.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cmb_baud.FormattingEnabled = true;
            this.cmb_baud.Items.AddRange(new object[] {
            "300",
            "600",
            "1200",
            "2400",
            "4800",
            "9600",
            "14400",
            "19200",
            "38400",
            "43000",
            "56000",
            "76800",
            "115200",
            "128000",
            "230400",
            "256000",
            "460800",
            "921600",
            "1382400"});
            this.cmb_baud.Location = new System.Drawing.Point(199, 22);
            this.cmb_baud.Name = "cmb_baud";
            this.cmb_baud.Size = new System.Drawing.Size(77, 20);
            this.cmb_baud.TabIndex = 25;
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(152, 25);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(41, 12);
            this.label3.TabIndex = 25;
            this.label3.Text = "波特率";
            // 
            // cmb_portname
            // 
            this.cmb_portname.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cmb_portname.FormattingEnabled = true;
            this.cmb_portname.Items.AddRange(new object[] {
            "COM1",
            "COM2",
            "COM3",
            "COM4",
            "COM5",
            "COM6",
            "COM7",
            "COM8",
            "COM9",
            "COM10"});
            this.cmb_portname.Location = new System.Drawing.Point(52, 22);
            this.cmb_portname.Name = "cmb_portname";
            this.cmb_portname.Size = new System.Drawing.Size(85, 20);
            this.cmb_portname.TabIndex = 23;
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(17, 25);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(29, 12);
            this.label2.TabIndex = 0;
            this.label2.Text = "串口";
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.checkBox2);
            this.groupBox1.Controls.Add(this.button2);
            this.groupBox1.Controls.Add(this.button4);
            this.groupBox1.Controls.Add(this.checkBox1);
            this.groupBox1.Controls.Add(this.txt_length);
            this.groupBox1.Controls.Add(this.label8);
            this.groupBox1.Controls.Add(this.txt_startAddr1);
            this.groupBox1.Controls.Add(this.label7);
            this.groupBox1.Controls.Add(this.txt_slave1);
            this.groupBox1.Controls.Add(this.label11);
            this.groupBox1.Location = new System.Drawing.Point(11, 237);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(780, 65);
            this.groupBox1.TabIndex = 33;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "读操作";
            // 
            // checkBox2
            // 
            this.checkBox2.AutoSize = true;
            this.checkBox2.Location = new System.Drawing.Point(556, 26);
            this.checkBox2.Name = "checkBox2";
            this.checkBox2.Size = new System.Drawing.Size(66, 16);
            this.checkBox2.TabIndex = 43;
            this.checkBox2.Text = "HEX发送";
            this.checkBox2.UseVisualStyleBackColor = true;
            // 
            // button4
            // 
            this.button4.Location = new System.Drawing.Point(500, 18);
            this.button4.Name = "button4";
            this.button4.Size = new System.Drawing.Size(50, 30);
            this.button4.TabIndex = 42;
            this.button4.Text = "发送";
            this.button4.UseVisualStyleBackColor = true;
            this.button4.Click += new System.EventHandler(this.button4_Click);
            // 
            // checkBox1
            // 
            this.checkBox1.AutoSize = true;
            this.checkBox1.Location = new System.Drawing.Point(628, 26);
            this.checkBox1.Name = "checkBox1";
            this.checkBox1.Size = new System.Drawing.Size(66, 16);
            this.checkBox1.TabIndex = 41;
            this.checkBox1.Text = "HEX接收";
            this.checkBox1.UseVisualStyleBackColor = true;
            // 
            // txt_length
            // 
            this.txt_length.Location = new System.Drawing.Point(389, 20);
            this.txt_length.Name = "txt_length";
            this.txt_length.Size = new System.Drawing.Size(100, 21);
            this.txt_length.TabIndex = 5;
            // 
            // label8
            // 
            this.label8.AutoSize = true;
            this.label8.Location = new System.Drawing.Point(354, 26);
            this.label8.Name = "label8";
            this.label8.Size = new System.Drawing.Size(41, 12);
            this.label8.TabIndex = 4;
            this.label8.Text = "长度:";
            // 
            // txt_startAddr1
            // 
            this.txt_startAddr1.Location = new System.Drawing.Point(226, 20);
            this.txt_startAddr1.Name = "txt_startAddr1";
            this.txt_startAddr1.Size = new System.Drawing.Size(100, 21);
            this.txt_startAddr1.TabIndex = 3;
            // 
            // label7
            // 
            this.label7.AutoSize = true;
            this.label7.Location = new System.Drawing.Point(167, 26);
            this.label7.Name = "label7";
            this.label7.Size = new System.Drawing.Size(65, 12);
            this.label7.TabIndex = 2;
            this.label7.Text = "起始地址:";
            // 
            // txt_slave1
            // 
            this.txt_slave1.Location = new System.Drawing.Point(49, 20);
            this.txt_slave1.Name = "txt_slave1";
            this.txt_slave1.Size = new System.Drawing.Size(100, 21);
            this.txt_slave1.TabIndex = 1;
            // 
            // label11
            // 
            this.label11.AutoSize = true;
            this.label11.Location = new System.Drawing.Point(14, 26);
            this.label11.Name = "label11";
            this.label11.Size = new System.Drawing.Size(41, 12);
            this.label11.TabIndex = 0;
            this.label11.Text = "站号:";
            // 
            // groupBox2
            // 
            this.groupBox2.Controls.Add(this.label13);
            this.groupBox2.Controls.Add(this.txt_data);
            this.groupBox2.Controls.Add(this.label9);
            this.groupBox2.Controls.Add(this.txt_startAddr2);
            this.groupBox2.Controls.Add(this.label10);
            this.groupBox2.Controls.Add(this.txt_slave2);
            this.groupBox2.Controls.Add(this.label12);
            this.groupBox2.Location = new System.Drawing.Point(11, 310);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(780, 65);
            this.groupBox2.TabIndex = 34;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "写操作";
            // 
            // label13
            // 
            this.label13.AutoSize = true;
            this.label13.BackColor = System.Drawing.Color.Transparent;
            this.label13.ForeColor = System.Drawing.Color.Chocolate;
            this.label13.Location = new System.Drawing.Point(400, 44);
            this.label13.Name = "label13";
            this.label13.Size = new System.Drawing.Size(377, 12);
            this.label13.TabIndex = 13;
            this.label13.Text = "(数据之间用\'空格\'隔开,线圈数据用0或1表示,寄存器数据ushort类型)";
            // 
            // txt_data
            // 
            this.txt_data.Location = new System.Drawing.Point(417, 20);
            this.txt_data.Name = "txt_data";
            this.txt_data.Size = new System.Drawing.Size(346, 21);
            this.txt_data.TabIndex = 5;
            // 
            // label9
            // 
            this.label9.AutoSize = true;
            this.label9.Location = new System.Drawing.Point(354, 26);
            this.label9.Name = "label9";
            this.label9.Size = new System.Drawing.Size(65, 12);
            this.label9.TabIndex = 4;
            this.label9.Text = "数据数组:";
            // 
            // txt_startAddr2
            // 
            this.txt_startAddr2.Location = new System.Drawing.Point(226, 20);
            this.txt_startAddr2.Name = "txt_startAddr2";
            this.txt_startAddr2.Size = new System.Drawing.Size(100, 21);
            this.txt_startAddr2.TabIndex = 10;
            // 
            // label10
            // 
            this.label10.AutoSize = true;
            this.label10.Location = new System.Drawing.Point(167, 26);
            this.label10.Name = "label10";
            this.label10.Size = new System.Drawing.Size(65, 12);
            this.label10.TabIndex = 2;
            this.label10.Text = "起始地址:";
            // 
            // txt_slave2
            // 
            this.txt_slave2.Location = new System.Drawing.Point(49, 20);
            this.txt_slave2.Name = "txt_slave2";
            this.txt_slave2.Size = new System.Drawing.Size(100, 21);
            this.txt_slave2.TabIndex = 8;
            // 
            // label12
            // 
            this.label12.AutoSize = true;
            this.label12.Location = new System.Drawing.Point(14, 26);
            this.label12.Name = "label12";
            this.label12.Size = new System.Drawing.Size(41, 12);
            this.label12.TabIndex = 0;
            this.label12.Text = "站号:";
            // 
            // richTextBox1
            // 
            this.richTextBox1.Location = new System.Drawing.Point(11, 382);
            this.richTextBox1.Name = "richTextBox1";
            this.richTextBox1.Size = new System.Drawing.Size(780, 203);
            this.richTextBox1.TabIndex = 35;
            this.richTextBox1.Text = "";
            this.richTextBox1.TextChanged += new System.EventHandler(this.richTextBox1_TextChanged);
            // 
            // cmb_DataFormat
            // 
            this.cmb_DataFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cmb_DataFormat.FormattingEnabled = true;
            this.cmb_DataFormat.Location = new System.Drawing.Point(463, 26);
            this.cmb_DataFormat.Name = "cmb_DataFormat";
            this.cmb_DataFormat.Size = new System.Drawing.Size(81, 20);
            this.cmb_DataFormat.TabIndex = 42;
            this.cmb_DataFormat.SelectedIndexChanged += new System.EventHandler(this.cmb_DataFormat_SelectedIndexChanged);
            // 
            // label15
            // 
            this.label15.AutoSize = true;
            this.label15.Location = new System.Drawing.Point(394, 30);
            this.label15.Name = "label15";
            this.label15.Size = new System.Drawing.Size(65, 12);
            this.label15.TabIndex = 41;
            this.label15.Text = "数据格式:";
            // 
            // cmb_VarType
            // 
            this.cmb_VarType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cmb_VarType.FormattingEnabled = true;
            this.cmb_VarType.Location = new System.Drawing.Point(302, 26);
            this.cmb_VarType.Name = "cmb_VarType";
            this.cmb_VarType.Size = new System.Drawing.Size(74, 20);
            this.cmb_VarType.TabIndex = 39;
            this.cmb_VarType.SelectedIndexChanged += new System.EventHandler(this.cmb_VarType_SelectedIndexChanged);
            // 
            // label14
            // 
            this.label14.AutoSize = true;
            this.label14.Location = new System.Drawing.Point(243, 29);
            this.label14.Name = "label14";
            this.label14.Size = new System.Drawing.Size(53, 12);
            this.label14.TabIndex = 38;
            this.label14.Text = "变量类型";
            // 
            // port
            // 
            this.port.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.port_DataReceived);
            // 
            // groupBox4
            // 
            this.groupBox4.Controls.Add(this.cmb_DataFormat);
            this.groupBox4.Controls.Add(this.button1);
            this.groupBox4.Controls.Add(this.label1);
            this.groupBox4.Controls.Add(this.label15);
            this.groupBox4.Controls.Add(this.comboBox1);
            this.groupBox4.Controls.Add(this.cmb_VarType);
            this.groupBox4.Controls.Add(this.label14);
            this.groupBox4.Location = new System.Drawing.Point(11, 170);
            this.groupBox4.Name = "groupBox4";
            this.groupBox4.Size = new System.Drawing.Size(778, 61);
            this.groupBox4.TabIndex = 43;
            this.groupBox4.TabStop = false;
            this.groupBox4.Text = "数据参数";
            // 
            // gbTCP
            // 
            this.gbTCP.Controls.Add(this.btnOpen);
            this.gbTCP.Controls.Add(this.label16);
            this.gbTCP.Controls.Add(this.tbTCPIP);
            this.gbTCP.Controls.Add(this.tbTCPPort);
            this.gbTCP.Controls.Add(this.tbLocalPort);
            this.gbTCP.Controls.Add(this.label17);
            this.gbTCP.Controls.Add(this.label18);
            this.gbTCP.Location = new System.Drawing.Point(12, 31);
            this.gbTCP.Name = "gbTCP";
            this.gbTCP.Size = new System.Drawing.Size(778, 58);
            this.gbTCP.TabIndex = 44;
            this.gbTCP.TabStop = false;
            this.gbTCP.Text = "TCP参数";
            // 
            // label16
            // 
            this.label16.AutoSize = true;
            this.label16.Location = new System.Drawing.Point(7, 29);
            this.label16.Name = "label16";
            this.label16.Size = new System.Drawing.Size(71, 12);
            this.label16.TabIndex = 39;
            this.label16.Text = "PLC的IP地址";
            // 
            // tbTCPIP
            // 
            this.tbTCPIP.Location = new System.Drawing.Point(84, 25);
            this.tbTCPIP.Name = "tbTCPIP";
            this.tbTCPIP.Size = new System.Drawing.Size(100, 21);
            this.tbTCPIP.TabIndex = 38;
            this.tbTCPIP.Text = "127.0.0.1";
            this.tbTCPIP.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            // 
            // tbTCPPort
            // 
            this.tbTCPPort.Location = new System.Drawing.Point(270, 25);
            this.tbTCPPort.Name = "tbTCPPort";
            this.tbTCPPort.Size = new System.Drawing.Size(44, 21);
            this.tbTCPPort.TabIndex = 40;
            this.tbTCPPort.Text = "502";
            this.tbTCPPort.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            // 
            // tbLocalPort
            // 
            this.tbLocalPort.Location = new System.Drawing.Point(405, 25);
            this.tbLocalPort.Name = "tbLocalPort";
            this.tbLocalPort.Size = new System.Drawing.Size(44, 21);
            this.tbLocalPort.TabIndex = 36;
            this.tbLocalPort.Text = "0";
            this.tbLocalPort.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.tbLocalPort.Visible = false;
            // 
            // label17
            // 
            this.label17.AutoSize = true;
            this.label17.Location = new System.Drawing.Point(219, 28);
            this.label17.Name = "label17";
            this.label17.Size = new System.Drawing.Size(47, 12);
            this.label17.TabIndex = 41;
            this.label17.Text = "PLC端口";
            // 
            // label18
            // 
            this.label18.AutoSize = true;
            this.label18.Location = new System.Drawing.Point(348, 28);
            this.label18.Name = "label18";
            this.label18.Size = new System.Drawing.Size(53, 12);
            this.label18.TabIndex = 37;
            this.label18.Text = "本机端口";
            this.label18.Visible = false;
            // 
            // rbRTU
            // 
            this.rbRTU.AutoSize = true;
            this.rbRTU.Checked = true;
            this.rbRTU.Location = new System.Drawing.Point(158, 10);
            this.rbRTU.Name = "rbRTU";
            this.rbRTU.Size = new System.Drawing.Size(41, 16);
            this.rbRTU.TabIndex = 45;
            this.rbRTU.TabStop = true;
            this.rbRTU.Text = "RTU";
            this.rbRTU.UseVisualStyleBackColor = true;
            this.rbRTU.CheckedChanged += new System.EventHandler(this.rb_CheckedChanged);
            // 
            // rbTCP
            // 
            this.rbTCP.AutoSize = true;
            this.rbTCP.Location = new System.Drawing.Point(211, 9);
            this.rbTCP.Name = "rbTCP";
            this.rbTCP.Size = new System.Drawing.Size(41, 16);
            this.rbTCP.TabIndex = 46;
            this.rbTCP.TabStop = true;
            this.rbTCP.Text = "TCP";
            this.rbTCP.UseVisualStyleBackColor = true;
            this.rbTCP.CheckedChanged += new System.EventHandler(this.rb_CheckedChanged);
            // 
            // btnOpen
            // 
            this.btnOpen.Location = new System.Drawing.Point(663, 23);
            this.btnOpen.Name = "btnOpen";
            this.btnOpen.Size = new System.Drawing.Size(98, 22);
            this.btnOpen.TabIndex = 42;
            this.btnOpen.Text = "打开连接";
            this.btnOpen.UseVisualStyleBackColor = true;
            this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 597);
            this.Controls.Add(this.rbTCP);
            this.Controls.Add(this.rbRTU);
            this.Controls.Add(this.gbTCP);
            this.Controls.Add(this.groupBox4);
            this.Controls.Add(this.groupBox2);
            this.Controls.Add(this.richTextBox1);
            this.Controls.Add(this.gbRTU);
            this.Controls.Add(this.groupBox1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
            this.Name = "Form1";
            this.Text = "Modbus Rtu";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.gbRTU.ResumeLayout(false);
            this.gbRTU.PerformLayout();
            this.groupBox1.ResumeLayout(false);
            this.groupBox1.PerformLayout();
            this.groupBox2.ResumeLayout(false);
            this.groupBox2.PerformLayout();
            this.groupBox4.ResumeLayout(false);
            this.groupBox4.PerformLayout();
            this.gbTCP.ResumeLayout(false);
            this.gbTCP.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.ComboBox comboBox1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.GroupBox gbRTU;
        private System.Windows.Forms.ComboBox cmb_stopBits;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.ComboBox cmb_databBits;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.ComboBox cmb_parity;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.ComboBox cmb_baud;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.ComboBox cmb_portname;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.TextBox txt_length;
        private System.Windows.Forms.Label label8;
        private System.Windows.Forms.TextBox txt_startAddr1;
        private System.Windows.Forms.Label label7;
        private System.Windows.Forms.TextBox txt_slave1;
        private System.Windows.Forms.Label label11;
        private System.Windows.Forms.GroupBox groupBox2;
        private System.Windows.Forms.TextBox txt_data;
        private System.Windows.Forms.Label label9;
        private System.Windows.Forms.TextBox txt_startAddr2;
        private System.Windows.Forms.Label label10;
        private System.Windows.Forms.TextBox txt_slave2;
        private System.Windows.Forms.Label label12;
        private System.Windows.Forms.RichTextBox richTextBox1;
        private System.Windows.Forms.Label label13;
        private System.Windows.Forms.ComboBox cmb_VarType;
        private System.Windows.Forms.Label label14;
        private System.IO.Ports.SerialPort port;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.CheckBox checkBox1;
        private System.Windows.Forms.Button button4;
        private System.Windows.Forms.CheckBox checkBox2;
        private System.Windows.Forms.ComboBox cmb_DataFormat;
        private System.Windows.Forms.Label label15;
        private System.Windows.Forms.GroupBox groupBox4;
        private System.Windows.Forms.GroupBox gbTCP;
        internal System.Windows.Forms.Label label16;
        internal System.Windows.Forms.TextBox tbTCPIP;
        internal System.Windows.Forms.TextBox tbTCPPort;
        internal System.Windows.Forms.TextBox tbLocalPort;
        internal System.Windows.Forms.Label label17;
        internal System.Windows.Forms.Label label18;
        private System.Windows.Forms.RadioButton rbRTU;
        private System.Windows.Forms.RadioButton rbTCP;
        private System.Windows.Forms.Button btnOpen;
    }
}


主程序代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.IO.Ports;
using System.Drawing.Text;
using System.Windows.Forms.VisualStyles;
using System.Timers;
using System.CodeDom.Compiler;
using System.Net;

namespace ModbusRtu
{
    public partial class Form1 : Form
    {
        #region 参数配置
        //private static SerialPort port;
        //串口发送数据数组
        private byte[] SendBuff;
        //写线圈或写寄存器数组
        private bool[] coilsBuffer /*= new bool[16]*/;
        private ushort[] UshortBuffer;
        private short[] ShortBuffer;
        private uint[] UintBuffer;
        private int[] IntBuffer;
        private float[] FloatBuffer;
        //功能码
        private string functionCode;
        //功能码序号
        private int functionOder;
        //参数(分别为从站地址,起始地址,长度)
        private byte slaveAddress;
        private ushort startAddress;
        private ushort numberOfPoints;
        //串口参数
        private string portName;
        private int baudRate;
        private Parity parity;
        private int dataBits;
        private StopBits stopBits;
        //自动测试标志位
        private bool AutoFlag = false;
        //获取当前时间
        private System.DateTime Current_time;

        //定时器初始化
        private System.Timers.Timer t = new System.Timers.Timer(1000);

        private const int WM_DEVICE_CHANGE = 0x219;            //设备改变           
        private const int DBT_DEVICEARRIVAL = 0x8000;          //设备插入
        private const int DBT_DEVICE_REMOVE_COMPLETE = 0x8004; //设备移除

        private VarType vartype;
        //数据格式
        private DataFormat dataFormat;
        private string InPutstr;

        Socket socketSend;
        private bool IsOpen = false;
        private int Port;
        private string IP;
        #endregion
        public enum VarType
        {
            Bit = 0,
            Byte = 1,
            Word = 2,
            DWord = 3,
            Int = 4,
            DInt = 5,
            Real = 6,
            String = 7,
            Timer = 8,
            Counter = 9
        }
        public enum DataFormat
        {
            ABCD = 0,
            BADC = 1,
            CDAB = 2,
            DCBA = 3
        }
        public Form1()
        {
            InitializeComponent();
            GetSerialLstTb1();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //界面初始化
            gbRTU.Enabled = rbRTU.Checked;
            gbTCP.Enabled = rbTCP.Checked;
            cmb_portname.SelectedIndex = 0;
            cmb_baud.SelectedIndex = 5;
            cmb_parity.SelectedIndex = 2;
            cmb_databBits.SelectedIndex = 1;
            cmb_stopBits.SelectedIndex = 0;
            cmb_VarType.DataSource = Enum.GetNames(typeof(VarType));
            cmb_VarType.SelectedIndex = 2;
            vartype = (VarType)Enum.Parse(typeof(VarType), cmb_VarType.SelectedItem.ToString(), false);
            cmb_DataFormat.DataSource = Enum.GetNames(typeof(DataFormat));
            cmb_DataFormat.SelectedIndex = 0;
            dataFormat = (DataFormat)Enum.Parse(typeof(DataFormat), cmb_DataFormat.SelectedItem.ToString(), false);
            button1.Enabled = false;
        }



        /// <summary>
        /// 设置读参数
        /// </summary>
        private bool SetReadParameters()
        {
            if (txt_slave1.Text == ""|| txt_startAddr1.Text == "" || txt_length.Text == "")
            {
                MessageBox.Show("请填写读参数!");
                return false;
            }
            else
            {
                slaveAddress = byte.Parse(txt_slave1.Text);
                startAddress = ushort.Parse(txt_startAddr1.Text);
                numberOfPoints = ushort.Parse(txt_length.Text);
                return true;
            }
        }

        /// <summary>
        /// 设置写参数
        /// </summary>
        private bool SetWriteParametes()
        {
            if (txt_startAddr2.Text == "" || txt_slave2.Text == "" || txt_data.Text == "")
            {
                MessageBox.Show("请填写写参数!");
                return false;
            }
            else
            {
                InPutstr = txt_data.Text;
                slaveAddress = byte.Parse(txt_slave2.Text);
                startAddress = ushort.Parse(txt_startAddr2.Text);
                //判断是否写线圈
                if (functionOder == 4 || functionOder == 6)
                {
                    string[] strarr = txt_data.Text.Split(' ');
                    numberOfPoints = (ushort)strarr.Length;
                    if (strarr.Length % 8 == 0)
                    {
                        coilsBuffer = new bool[strarr.Length];
                    }
                    else
                    {
                        coilsBuffer = new bool[strarr.Length + 8 - strarr.Length % 8];
                    }
                    //转化为bool数组
                    for (int i = 0; i < coilsBuffer.Length; i++)
                    {
                        // strarr[i] == "0" ? coilsBuffer[i] = false : coilsBuffer[i] = true;
                        if (i < strarr.Length)
                        {
                            if (strarr[i] == "0")
                            {
                                coilsBuffer[i] = false;
                            }
                            else
                            {
                                coilsBuffer[i] = true;
                            }
                        }
                        else
                        {
                            coilsBuffer[i] = false;
                        }
                    }
                }
                else
                {
                    string[] strarr = txt_data.Text.Split(' ');
                    numberOfPoints = (ushort)strarr.Length;
                    switch (vartype)
                    {
                        case VarType.Word:
                            UshortBuffer = new ushort[strarr.Length];
                            for (int i = 0; i < strarr.Length; i++)
                            {
                                UshortBuffer[i] = ushort.Parse(strarr[i]);
                            }
                            break;
                        case VarType.DWord:
                            UintBuffer = new uint[strarr.Length];
                            for (int i = 0; i < strarr.Length; i++)
                            {
                                UintBuffer[i] = uint.Parse(strarr[i]);
                            }
                            break;
                        case VarType.Int:
                            ShortBuffer = new short[strarr.Length];
                            for (int i = 0; i < strarr.Length; i++)
                            {
                                ShortBuffer[i] = short.Parse(strarr[i]);
                            }
                            break;
                        case VarType.DInt:
                            IntBuffer = new int[strarr.Length];
                            for (int i = 0; i < strarr.Length; i++)
                            {
                                IntBuffer[i] = int.Parse(strarr[i]);
                            }
                            break;
                        case VarType.Real:
                            FloatBuffer = new float[strarr.Length];
                            for (int i = 0; i < strarr.Length; i++)
                            {
                                FloatBuffer[i] = float.Parse(strarr[i]);
                            }
                            break;
                        case VarType.String:
                        case VarType.Bit:
                        case VarType.Byte:
                        case VarType.Timer:
                        case VarType.Counter:
                            break;
                    }
                }
                return true;
            }
        }

        /// <summary>
        /// 创建委托,打印日志
        /// </summary>
        /// <param name="msg"></param>
        public void SetMsg(string msg)
        {
            richTextBox1.Invoke(new Action(() => { richTextBox1.AppendText(msg); }));
        }

        /// <summary>
        /// 清空日志
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
        }

        /// <summary>
        /// 单击button1事件,串口完成一次读/写操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //if (rbRTU.Checked)
                //{
                ExecuteFunction2();
                //}
                //else if (rbTCP.Checked)
                //{
                //    ExecuteFunction();
                //}
            }
            catch (Exception)
            {
                MessageBox.Show("初始化异常");
            }
        }
        /// <summary>
        /// 读取数据时,失能写数据;写数据时,失能读数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox1.SelectedIndex >= 4)
            {
                groupBox2.Enabled = true;
                groupBox1.Enabled = false;
            }
            else
            {
                groupBox1.Enabled = true;
                groupBox2.Enabled = false;
            }
            //委托事件,在主线程中创建的控件,在子线程中读取设置控件的属性会出现异常,使用Invoke方法可以解决
            comboBox1.Invoke(new Action(() => { functionCode = comboBox1.SelectedItem.ToString(); functionOder = comboBox1.SelectedIndex; }));
        }

        /// <summary>
        /// 将打印日志显示到最新接收到的符号位置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            this.richTextBox1.SelectionStart = int.MaxValue;
            this.richTextBox1.ScrollToCaret();
        }


        #region 串口下拉列表刷新
        /// <summary>
        /// 刷新下拉列表显示
        /// </summary>
        private void GetSerialLstTb1()
        {
            //清除cmb_portname显示
            cmb_portname.SelectedIndex = -1;
            cmb_portname.Items.Clear();
            //获取串口列表
            string[] serialLst = SerialPort.GetPortNames();
            if (serialLst.Length > 0)
            {
                //取串口进行排序
                Array.Sort(serialLst);
                //将串口列表输出到cmb_portname
                cmb_portname.Items.AddRange(serialLst);
                cmb_portname.SelectedIndex = 0;
            }
        }
        #endregion

        private void button3_Click(object sender, EventArgs e)
        {
            if (button3.Text == "打开串口")
            {//如果按钮显示的是打开串口
                try
                {
                    //防止意外错误
                    if (!InitPortParameter())
                    {
                        return;
                    }
                    port.Open();//打开串口
                    button1.Enabled = true;
                    button3.Text = "关闭串口";//按钮显示关闭串口
                }
                catch (Exception err)
                {
                    MessageBox.Show("打开失败" + err.ToString(), "提示!");//对话框显示打开失败
                }
            }
            else
            {//要关闭串口
                try
                {//防止意外错误
                    port.Close();//关闭串口
                    button1.Enabled = false;
                }
                catch (Exception) { }
                button3.Text = "打开串口";//按钮显示打开
            }
        }
        /// <summary>
        /// 串口参数获取
        /// </summary>
        /// <returns></返回串口配置参数>
        private bool InitPortParameter()
        {
            if (rbRTU.Checked)
            {
                if (cmb_portname.SelectedIndex < 0 || cmb_baud.SelectedIndex < 0 || cmb_parity.SelectedIndex < 0 || cmb_databBits.SelectedIndex < 0 || cmb_stopBits.SelectedIndex < 0)
                {
                    MessageBox.Show("请选择串口参数");
                    return false;
                }
                else
                {
                    port.PortName = cmb_portname.SelectedItem.ToString();
                    port.BaudRate = int.Parse(cmb_baud.SelectedItem.ToString());
                    port.DataBits = int.Parse(cmb_databBits.SelectedItem.ToString());
                    switch (cmb_parity.SelectedItem.ToString())
                    {
                        case "奇":
                            port.Parity = Parity.Odd;
                            break;
                        case "偶":
                            port.Parity = Parity.Even;
                            break;
                        case "无":
                            port.Parity = Parity.None;
                            break;
                        default:
                            break;
                    }
                    switch (cmb_stopBits.SelectedItem.ToString())
                    {
                        case "1":
                            port.StopBits = StopBits.One;
                            break;
                        case "2":
                            port.StopBits = StopBits.Two;
                            break;
                        case "1.5":
                            port.StopBits = StopBits.OnePointFive;
                            break;
                        default:
                            break;
                    }

                    //port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
                    return true;
                }
            }
            if (rbTCP.Checked)
            {
                if (tbTCPIP.Text.Split('.').Length != 4 || !int.TryParse(tbTCPPort.Text, out Port))
                {
                    MessageBox.Show("请选择端口参数");
                    return false;
                }
                else
                {
                    IP = tbTCPIP.Text;
                    Port = Convert.ToInt32(tbTCPPort.Text);
                    return true;
                }
            }
            return true;
        }
        #region TCP收/发
        private void ExecuteFunction()
        {

        }
        #endregion
        #region 串口收/发
        private void ExecuteFunction2()
        {
            Current_time = System.DateTime.Now;
            try
            {
                dataFormat = (DataFormat)Enum.Parse(typeof(DataFormat), cmb_DataFormat.SelectedItem.ToString(), false);
                vartype = (VarType)Enum.Parse(typeof(VarType), cmb_VarType.SelectedItem.ToString(), false);
                if (rbRTU.Checked)
                {
                    if (port.IsOpen == false)
                    {
                        MessageBox.Show("串口未打开");
                        return;
                    }
                }
                else if (rbTCP.Checked)
                {
                    if (IsOpen==false)
                    {
                        MessageBox.Show("未连接");
                        return;
                    }
                }
                if (functionCode != null)
                {
                    switch (functionCode)
                    {
                        case "01 Read Coils"://读取输出线圈
                            if (!SetReadParameters())
                            {
                                return;
                            }
                            try
                            {
                                switch (vartype)
                                {
                                    case VarType.Bit:
                                        MyRead(01);
                                        break;
                                    case VarType.Word:
                                    case VarType.DWord:
                                    case VarType.Int:
                                    case VarType.DInt:
                                    case VarType.Real:
                                    case VarType.String:
                                    case VarType.Byte:
                                    case VarType.Timer:
                                    case VarType.Counter:
                                        MessageBox.Show("读取失败,变量类型不支持");
                                        break;
                                }
                            }
                            catch (Exception)
                            {
                                MessageBox.Show("参数配置错误");
                                AutoFlag = false;
                                break;
                            }
                            break;
                        case "02 Read DisCrete Inputs"://读取输入线圈/离散量线圈
                            if (!SetReadParameters())
                            {
                                return;
                            }
                            try
                            {
                                switch (vartype)
                                {
                                    case VarType.Bit:
                                        MyRead(02);
                                        break;
                                    case VarType.Word:
                                    case VarType.DWord:
                                    case VarType.Int:
                                    case VarType.DInt:
                                    case VarType.Real:
                                    case VarType.String:
                                    case VarType.Byte:
                                    case VarType.Timer:
                                    case VarType.Counter:
                                        MessageBox.Show("读取失败,变量类型不支持");
                                        break;
                                }
                            }
                            catch (Exception)
                            {
                                MessageBox.Show("参数配置错误");
                                AutoFlag = false;
                                break;
                            }
                            break;
                        case "03 Read Holding Registers"://读取保持寄存器
                            if (!SetReadParameters())
                            {
                                return;
                            }
                            try
                            {
                                switch (vartype)
                                {
                                    case VarType.Word:
                                    case VarType.Int:
                                        MyRead(03);
                                        break;
                                    case VarType.DWord:
                                    case VarType.DInt:
                                    case VarType.Real:
                                        MyRead(03, 2);
                                        break;
                                    case VarType.Bit:
                                    case VarType.String:
                                    case VarType.Byte:
                                    case VarType.Timer:
                                    case VarType.Counter:
                                        MessageBox.Show("读取失败,变量类型不支持");
                                        break;
                                }
                            }
                            catch (Exception)
                            {
                                MessageBox.Show("参数配置错误");
                                AutoFlag = false;
                                break;
                            }
                            break;
                        case "04 Read Input Registers"://读取输入寄存器
                            if (!SetReadParameters())
                            {
                                return;
                            }
                            try
                            {
                                switch (vartype)
                                {
                                    case VarType.Word:
                                    case VarType.Int:
                                        MyRead(04);
                                        break;
                                    case VarType.DWord:
                                    case VarType.DInt:
                                    case VarType.Real:
                                        MyRead(04, 2);
                                        break;
                                    case VarType.Bit:
                                    case VarType.String:
                                    case VarType.Byte:
                                    case VarType.Timer:
                                    case VarType.Counter:
                                        MessageBox.Show("读取失败,变量类型不支持");
                                        break;
                                }
                            }
                            catch (Exception)
                            {
                                MessageBox.Show("参数配置错误");
                                AutoFlag = false;
                                break;
                            }
                            break;
                        case "05 Write Single Coil"://写单个线圈
                            if (!SetWriteParametes())
                            {
                                return;
                            }
                            try
                            {
                                switch (vartype)
                                {
                                    case VarType.Bit:
                                        MyWrite(05);
                                        break;
                                    case VarType.Word:
                                    case VarType.Int:
                                    case VarType.DWord:
                                    case VarType.DInt:
                                    case VarType.Real:
                                    case VarType.String:
                                    case VarType.Byte:
                                    case VarType.Timer:
                                    case VarType.Counter:
                                        MessageBox.Show("写入失败,变量类型不支持");
                                        break;
                                }
                            }
                            catch (Exception)
                            {
                                MessageBox.Show("参数配置错误");
                                AutoFlag = false;
                                break;
                            }
                            break;
                        case "06 Write Single Registers"://写单个保持寄存器
                            if (!SetWriteParametes())
                            {
                                return;
                            }
                            try
                            {
                                switch (vartype)
                                {
                                    case VarType.Word:
                                    case VarType.Int:
                                        MyWrite(06);
                                        break;
                                    case VarType.DWord:
                                    case VarType.DInt:
                                    case VarType.Real:
                                    case VarType.Bit:
                                    case VarType.String:
                                    case VarType.Byte:
                                    case VarType.Timer:
                                    case VarType.Counter:
                                        MessageBox.Show("写入失败,变量类型不支持");
                                        break;
                                }
                            }
                            catch (Exception)
                            {
                                MessageBox.Show("参数配置错误");
                                AutoFlag = false;
                                break;
                            }
                            break;
                        case "0F Write Multiple Coils"://写一组线圈
                            if (!SetWriteParametes())
                            {
                                return;
                            }
                            try
                            {
                                switch (vartype)
                                {
                                    case VarType.Bit:
                                        MyWrite(0x0F);
                                        break;
                                    case VarType.Word:
                                    case VarType.Int:
                                    case VarType.DWord:
                                    case VarType.DInt:
                                    case VarType.Real:
                                    case VarType.String:
                                    case VarType.Byte:
                                    case VarType.Timer:
                                    case VarType.Counter:
                                        MessageBox.Show("写入失败,变量类型不支持");
                                        break;
                                }
                            }
                            catch (Exception)
                            {
                                MessageBox.Show("参数配置错误");
                                AutoFlag = false;
                                break;
                            }
                            break;
                        case "10 Write Multiple Registers"://写一组保持寄存器
                            if (!SetWriteParametes())
                            {
                                return;
                            }
                            switch (vartype)
                            {
                                case VarType.Word:
                                case VarType.Int:
                                case VarType.DWord:
                                case VarType.DInt:
                                case VarType.Real:
                                    MyWrite(0x10);
                                    break;
                                case VarType.Bit:
                                case VarType.String:
                                case VarType.Byte:
                                case VarType.Timer:
                                case VarType.Counter:
                                    MessageBox.Show("写入失败,变量类型不支持");
                                    break;
                            }
                            break;
                        default:
                            break;
                    }

                }
                else
                {
                    MessageBox.Show("请选择功能码!");
                }
                //port.Close();
            }
            catch (Exception ex)
            {
                //port.Close();
                //button1.Enabled = false;
                //button3.Text = "打开串口";//按钮显示打开
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

        byte addH;
        byte addL;
        byte lenH;
        byte lenL;
        ushort num = 0;
        //01 01 00 00 00 0A BC 0D
        //01 01 02 05 00 BA AC

        //01 02 00 00 00 0A F8 0D
        //01 02 02 25 01 62 E8

        //01 03 00 00 00 0D 84 0F
        //01 03 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D3 C2

        //01 04 00 00 00 0D 31 CF
        //01 04 1A 00 00 00 6F 00 00 00 00 01 4D 00 00 00 00 01 BC 00 00 02 2B 00 00 00 DE 00 00 6A 13
        /// <summary>
        /// 读命令
        /// </summary>
        /// <param name="f">功能码</param>
        /// <param name="length">16位数据长度为去1,32位数据长度位2</param>
        private void MyRead(byte f, int length = 1)
        {        
            UshortToHex(ref addL, ref addH, startAddress);
            UshortToHex(ref lenL, ref lenH, (ushort)(numberOfPoints * length));
            byte[] byteArray1 = { slaveAddress, f, addH, addL, lenH, lenL };
            UintToHex(ref L, ref H, GetCRC16(byteArray1));
            byte[] byteArray2 = { slaveAddress, f, addH, addL, lenH, lenL, L, H };
            if (rbRTU.Checked)
            {
                port.Write(byteArray2, 0, byteArray2.Length);
            }
            else if (rbTCP.Checked)
            {
                num++;
                byte[] bytenum = BitConverter.GetBytes((int)num);
                byte[] byteArray3 = { bytenum[1], bytenum[0], 0, 0, 0, 6, slaveAddress, f, addH, addL, lenH, lenL };
                socketSend.Send(byteArray3);
            }
        }

        //01 05 00 00 FF 00 8C 3A
        //01 05 00 00 FF 00 8C 3A

        //01 06 00 00 00 02 08 0B
        //01 06 00 00 00 02 08 0B

        //01 0F 00 00 00 0A 02 09 00 E3 68
        //01 0F 00 00 00 0A D5 CC

        //01 0F 00 00 00 19 04 09 00 00 00 C2 7D
        //01 0F 00 00 00 19 94 01

        //01 0F 00 00 00 19 04 09 50 40 00 F3 AC
        //01 0F 00 00 00 19 94 01

        /// <summary>
        /// 写命令 通断标志为FF00H表示写ON,0000H表示写OFF
        /// </summary>
        /// <param name="f">功能码</param>
        private void MyWrite(byte f)
        {
            byte[] dataBuff0 = { 0, 0 };
            byte[] intBuff = { 0, 0, 0, 0 };
            byte[] lenghtBuff = { 0, 0, 0, 0 };
            byte[] dataBuff;
            int[] int1;
            List<byte> frameBytes = new List<byte>();

            UshortToHex(ref addL, ref addH, startAddress);
            if (f == 0x05)
            {
                if (coilsBuffer[0])
                {
                    dataBuff0[0] = 0xFF;
                    dataBuff0[1] = 0x00;
                }
                else
                {
                    dataBuff0[0] = 0x00;
                    dataBuff0[1] = 0x00;
                }
            }
            else if (f == 0x06)
            {
                switch (vartype)
                {
                    case VarType.Word:
                        dataBuff0[0] = (byte)((0xff00 & UshortBuffer[0]) >> 8);
                        dataBuff0[1] = (byte)(0xff & UshortBuffer[0]);
                        //dataBuff0 = GetIntByteArray(dataBuff0, 0, dataFormat);
                        break;
                    case VarType.Int:
                        dataBuff0[0] = (byte)((0xff00 & ShortBuffer[0]) >> 8);
                        dataBuff0[1] = (byte)(0xff & ShortBuffer[0]);
                        //dataBuff0 = GetIntByteArray(dataBuff0, 0, dataFormat);
                        break;
                    case VarType.DWord:
                    case VarType.DInt:
                    case VarType.Real:
                    case VarType.Bit:
                    case VarType.String:
                    case VarType.Byte:
                    case VarType.Timer:
                    case VarType.Counter:
                        break;
                }
            }
            else if (f == 0x0F)
            {
                int1 = new int[(coilsBuffer.Length / 4)];
                intBuff = BitConverter.GetBytes(numberOfPoints);
                for (int i = 0; i < coilsBuffer.Length; i += 4)
                {
                    int1[i / 4] = Convert.ToInt32(coilsBuffer[i]) + Convert.ToInt32(coilsBuffer[i + 1]) * 2 + Convert.ToInt32(coilsBuffer[i + 2]) * 4 + Convert.ToInt32(coilsBuffer[i + 3]) * 8;
                }
                dataBuff = new byte[coilsBuffer.Length / 8];
                for (int i = 0; i < int1.Length; i += 2)
                {
                    dataBuff[i / 2] = (byte)(int1[i] + int1[i + 1] * 16);
                }
                if (rbRTU.Checked)
                {
                    frameBytes.Clear();
                    frameBytes.Add(slaveAddress);
                    frameBytes.Add(f);
                    frameBytes.Add(addH);
                    frameBytes.Add(addL);
                    frameBytes.Add(intBuff[1]);
                    frameBytes.Add(intBuff[0]);
                    frameBytes.Add((byte)dataBuff.Length);
                    for (int i = 0; i < dataBuff.Length; i++)
                    {
                        frameBytes.Add(dataBuff[i]);
                    }
                    byte[] byteArray1 = frameBytes.ToArray();//list转byte[]
                    UintToHex(ref L, ref H, GetCRC16(byteArray1));
                    frameBytes.Add(L);
                    frameBytes.Add(H);
                    byte[] byteArray2 = frameBytes.ToArray();
                    port.Write(byteArray2, 0, byteArray2.Length);
                }
                else if (rbTCP.Checked)
                {
                    num++;
                    lenghtBuff = BitConverter.GetBytes(dataBuff.Length + 7);
                    frameBytes.Clear();
                    byte[] bytenum = BitConverter.GetBytes((int)num);
                    frameBytes.Add(bytenum[1]);
                    frameBytes.Add(bytenum[0]);
                    frameBytes.Add(0);
                    frameBytes.Add(0);
                    frameBytes.Add(lenghtBuff[1]);
                    frameBytes.Add(lenghtBuff[0]);
                    frameBytes.Add(slaveAddress);
                    frameBytes.Add(f);
                    frameBytes.Add(addH);
                    frameBytes.Add(addL);
                    frameBytes.Add(intBuff[1]);
                    frameBytes.Add(intBuff[0]);
                    frameBytes.Add((byte)dataBuff.Length);
                    for (int i = 0; i < dataBuff.Length; i++)
                    {
                        frameBytes.Add(dataBuff[i]);
                    }
                    byte[] byteArray3 = frameBytes.ToArray();//list转byte[]
                    socketSend.Send(byteArray3);
                }
            }
            else if (f == 0x10)
            {
                byte[] temp = { 0, 0, 0, 0 };
                if (rbRTU.Checked)
                {
                    frameBytes.Clear();
                    frameBytes.Add(slaveAddress);
                    frameBytes.Add(f);
                    frameBytes.Add(addH);
                    frameBytes.Add(addL);
                }
                else if (rbTCP.Checked)
                {
                    num++;
                    frameBytes.Clear();
                    byte[] bytenum = BitConverter.GetBytes((int)num);
                    frameBytes.Add(bytenum[1]);
                    frameBytes.Add(bytenum[0]);
                    frameBytes.Add(0);
                    frameBytes.Add(0);
                }
                switch (vartype)
                {
                    case VarType.Word:
                        byte[] UshortBuff = new byte[UshortBuffer.Length * 2];
                        for (int i = 0; i < UshortBuff.Length; i += 2)
                        {
                            UshortBuff[i] = (byte)((0xff00 & UshortBuffer[i / 2]) >> 8);
                            UshortBuff[i + 1] = (byte)(0xff & UshortBuffer[i / 2]);
                        }
                        intBuff = BitConverter.GetBytes(numberOfPoints);
                        if (rbTCP.Checked)
                        {
                            lenghtBuff = BitConverter.GetBytes(UshortBuff.Length + 7);
                            frameBytes.Add(lenghtBuff[1]);
                            frameBytes.Add(lenghtBuff[0]);
                            frameBytes.Add(slaveAddress);
                            frameBytes.Add(f);
                            frameBytes.Add(addH);
                            frameBytes.Add(addL);
                        }
                        frameBytes.Add(intBuff[1]);
                        frameBytes.Add(intBuff[0]);
                        frameBytes.Add((byte)UshortBuff.Length);
                        for (int i = 0; i < UshortBuff.Length; i++)
                        {
                            frameBytes.Add(UshortBuff[i]);
                        }
                        byte[] byteArray10 = frameBytes.ToArray();//list转byte[]
                        if (rbTCP.Checked)
                        {
                            socketSend.Send(byteArray10);
                        }
                        if (rbRTU.Checked)
                        {
                            UintToHex(ref L, ref H, GetCRC16(byteArray10));
                            frameBytes.Add(L);
                            frameBytes.Add(H);
                            byte[] byteArray20 = frameBytes.ToArray();
                            port.Write(byteArray20, 0, byteArray20.Length);
                        }
                        break;
                    case VarType.Int:
                        byte[] ShortBuff = new byte[ShortBuffer.Length * 2];
                        for (int i = 0; i < ShortBuff.Length; i += 2)
                        {
                            ShortBuff[i] = (byte)((0xff00 & ShortBuffer[i / 2]) >> 8);
                            ShortBuff[i + 1] = (byte)(0xff & ShortBuffer[i / 2]);
                        }
                        intBuff = BitConverter.GetBytes(numberOfPoints);
                        if (rbTCP.Checked)
                        {
                            lenghtBuff = BitConverter.GetBytes(ShortBuff.Length + 7);
                            frameBytes.Add(lenghtBuff[1]);
                            frameBytes.Add(lenghtBuff[0]);
                            frameBytes.Add(slaveAddress);
                            frameBytes.Add(f);
                            frameBytes.Add(addH);
                            frameBytes.Add(addL);
                        }
                        frameBytes.Add(intBuff[1]);
                        frameBytes.Add(intBuff[0]);
                        frameBytes.Add((byte)ShortBuff.Length);
                        for (int i = 0; i < ShortBuff.Length; i++)
                        {
                            frameBytes.Add(ShortBuff[i]);
                        }
                        byte[] byteArray11 = frameBytes.ToArray();//list转byte[]
                        if (rbTCP.Checked)
                        {
                            socketSend.Send(byteArray11);
                        }
                        if (rbRTU.Checked)
                        {
                            UintToHex(ref L, ref H, GetCRC16(byteArray11));
                            frameBytes.Add(L);
                            frameBytes.Add(H);
                            byte[] byteArray21 = frameBytes.ToArray();
                            port.Write(byteArray21, 0, byteArray21.Length);
                        }
                        break;
                    case VarType.DWord:
                        byte[] UintBuff = new byte[UintBuffer.Length * 4];
                        for (int i = 0; i < UintBuff.Length; i += 4)
                        {
                            UintBuff[i] = (byte)((0xff000000 & UintBuffer[i / 4]) >> 24);
                            UintBuff[i + 1] = (byte)((0xff0000 & UintBuffer[i / 4]) >> 16);
                            UintBuff[i + 2] = (byte)((0xff00 & UintBuffer[i / 4]) >> 8);
                            UintBuff[i + 3] = (byte)(0xff & UintBuffer[i / 4]);
                        }
                        intBuff = BitConverter.GetBytes(numberOfPoints * 2);
                        if (rbTCP.Checked)
                        {
                            lenghtBuff = BitConverter.GetBytes(UintBuff.Length + 7);
                            frameBytes.Add(lenghtBuff[1]);
                            frameBytes.Add(lenghtBuff[0]);
                            frameBytes.Add(slaveAddress);
                            frameBytes.Add(f);
                            frameBytes.Add(addH);
                            frameBytes.Add(addL);
                        }
                        frameBytes.Add(intBuff[1]);
                        frameBytes.Add(intBuff[0]);
                        frameBytes.Add((byte)UintBuff.Length);
                        for (int i = 0; i < UintBuff.Length; i += 4)
                        {
                            temp = GetSingleByteArray(UintBuff, i, dataFormat);
                            frameBytes.Add(temp[0]);
                            frameBytes.Add(temp[1]);
                            frameBytes.Add(temp[2]);
                            frameBytes.Add(temp[3]);
                        }
                        byte[] byteArray12 = frameBytes.ToArray();//list转byte[]if (rbTCP.Checked)
                        if (rbTCP.Checked)
                        {
                            socketSend.Send(byteArray12);
                        }
                        if (rbRTU.Checked)
                        {
                            UintToHex(ref L, ref H, GetCRC16(byteArray12));
                            frameBytes.Add(L);
                            frameBytes.Add(H);
                            byte[] byteArray22 = frameBytes.ToArray();
                            port.Write(byteArray22, 0, byteArray22.Length);
                        }
                        break;
                    case VarType.DInt:
                        byte[] IntBuff = new byte[IntBuffer.Length * 4];
                        for (int i = 0; i < IntBuff.Length; i += 4)
                        {
                            IntBuff[i] = (byte)((0xff000000 & IntBuffer[i / 4]) >> 24);
                            IntBuff[i + 1] = (byte)((0xff0000 & IntBuffer[i / 4]) >> 16);
                            IntBuff[i + 2] = (byte)((0xff00 & IntBuffer[i / 4]) >> 8);
                            IntBuff[i + 3] = (byte)(0xff & IntBuffer[i / 4]);
                        }
                        intBuff = BitConverter.GetBytes(numberOfPoints * 2);
                        if (rbTCP.Checked)
                        {
                            lenghtBuff = BitConverter.GetBytes(IntBuff.Length + 7);
                            frameBytes.Add(lenghtBuff[1]);
                            frameBytes.Add(lenghtBuff[0]);
                            frameBytes.Add(slaveAddress);
                            frameBytes.Add(f);
                            frameBytes.Add(addH);
                            frameBytes.Add(addL);
                        }
                        frameBytes.Add(intBuff[1]);
                        frameBytes.Add(intBuff[0]);
                        frameBytes.Add((byte)IntBuff.Length);
                        for (int i = 0; i < IntBuff.Length; i += 4)
                        {
                            temp = GetSingleByteArray(IntBuff, i, dataFormat);
                            frameBytes.Add(temp[0]);
                            frameBytes.Add(temp[1]);
                            frameBytes.Add(temp[2]);
                            frameBytes.Add(temp[3]);
                        }
                        byte[] byteArray13 = frameBytes.ToArray();//list转byte[]
                        if (rbTCP.Checked)
                        {
                            socketSend.Send(byteArray13);
                        }
                        if (rbRTU.Checked)
                        {
                            UintToHex(ref L, ref H, GetCRC16(byteArray13));
                            frameBytes.Add(L);
                            frameBytes.Add(H);
                            byte[] byteArray23 = frameBytes.ToArray();
                            port.Write(byteArray23, 0, byteArray23.Length);
                        }
                        break;
                    case VarType.Real:
                        byte[] FloatBuff = new byte[FloatBuffer.Length * 4];
                        for (int i = 0; i < FloatBuff.Length; i += 4)
                        {
                            temp = BitConverter.GetBytes(FloatBuffer[i / 4]);
                            temp = GetSingleByteArray(temp, 0, dataFormat);
                            FloatBuff[i] = temp[3];
                            FloatBuff[i + 1] = temp[2];
                            FloatBuff[i + 2] = temp[1];
                            FloatBuff[i + 3] = temp[0];
                        }
                        intBuff = BitConverter.GetBytes(numberOfPoints * 2);
                        if (rbTCP.Checked)
                        {
                            lenghtBuff = BitConverter.GetBytes(FloatBuff.Length + 7);
                            frameBytes.Add(lenghtBuff[1]);
                            frameBytes.Add(lenghtBuff[0]);
                            frameBytes.Add(slaveAddress);
                            frameBytes.Add(f);
                            frameBytes.Add(addH);
                            frameBytes.Add(addL);
                        }
                        frameBytes.Add(intBuff[1]);
                        frameBytes.Add(intBuff[0]);
                        frameBytes.Add((byte)FloatBuff.Length);
                        for (int i = 0; i < FloatBuff.Length; i++)
                        {
                            frameBytes.Add(FloatBuff[i]);
                        }
                        byte[] byteArray14 = frameBytes.ToArray();//list转byte[]
                        if (rbTCP.Checked)
                        {
                            socketSend.Send(byteArray14);
                        }
                        if (rbRTU.Checked)
                        {
                            UintToHex(ref L, ref H, GetCRC16(byteArray14));
                            frameBytes.Add(L);
                            frameBytes.Add(H);
                            byte[] byteArray24 = frameBytes.ToArray();
                            port.Write(byteArray24, 0, byteArray24.Length);
                        }
                        break;
                    case VarType.Bit:
                    case VarType.String:
                    case VarType.Byte:
                    case VarType.Timer:
                    case VarType.Counter:
                        break;
                }
            }
            if (f != 0x0f && f != 0x10)
            {
                byte[] byteArray1 = { slaveAddress, f, addH, addL, dataBuff0[0], dataBuff0[1] };
                UintToHex(ref L, ref H, GetCRC16(byteArray1));
                byte[] byteArray2 = { slaveAddress, f, addH, addL, dataBuff0[0], dataBuff0[1], L, H };
                if (rbRTU.Checked)
                {
                    port.Write(byteArray2, 0, byteArray2.Length);
                }
                else if (rbTCP.Checked)
                {
                    num++;
                    byte[] bytenum = BitConverter.GetBytes((int)num);
                    byte[] byteArray3 = { bytenum[1], bytenum[0], 0, 0, 0, 6, slaveAddress, f, addH, addL, dataBuff0[0], dataBuff0[1] };
                    socketSend.Send(byteArray3);
                }
            }

            //port.Write(byteArray2, 0, byteArray2.Length);
        }
        private void ResolutionCoils(byte[] buff1)//解析线圈
        {
            switch (vartype)
            {
                case VarType.Bit:
                    //byte[] buff1 = buff.Skip(3).Take(2).ToArray();
                    BitArray bitSet1 = new BitArray(buff1);//a为byte数组,bitSet是bool类型的数组
                    //for (int i = 0; i < bitSet1.Count; i++)
                    //{
                    //    coilsBuffer[i] = bitSet1[i];
                    //}
                    Current_time = System.DateTime.Now;
                    SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
                    for (int i = 0; i < numberOfPoints; i++)
                    {
                        //SetMsg(coilsBuffer[i] + " ");
                        SetMsg(bitSet1[i] + " ");
                    }
                    SetMsg("\r\n");
                    break;
                case VarType.Word:
                case VarType.DWord:
                case VarType.Int:
                case VarType.DInt:
                case VarType.Real:
                case VarType.String:
                case VarType.Byte:
                case VarType.Timer:
                case VarType.Counter:
                    MessageBox.Show("读取失败,变量类型不支持");
                    break;
            }
        }

        private void ResolutionRegisters(byte[] buff3)//解析寄存器
        {
            switch (vartype)
            {
                case VarType.Word:
                    string wordvalue = string.Empty;
                    buff3 = SwapAB(buff3);
                    if (buff3 != null && buff3.Length == numberOfPoints * 2)
                    {
                        for (int i = 0; i < buff3.Length; i += 2)
                        {
                            //wordvalue += BitConverter.ToUInt16(GetIntByteArray(buff3, i, dataFormat), 0).ToString() + " ";
                            wordvalue += BitConverter.ToUInt16(buff3.Skip(i).Take(2).ToArray(), 0).ToString() + " ";
                        }
                        Current_time = System.DateTime.Now;
                        SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
                        SetMsg(wordvalue + " ");
                        SetMsg("\r\n");
                    }
                    else
                    {
                        SetMsg("读取失败,请检查地址、类型及连接状态");
                        SetMsg("\r\n");
                    }
                    break;
                case VarType.DWord:
                    buff3 = SwapABCD(buff3);
                    string dwordvalue = string.Empty;
                    if (buff3 != null && buff3.Length == numberOfPoints * 4)
                    {
                        for (int i = 0; i < buff3.Length; i += 4)
                        {
                            dwordvalue += BitConverter.ToUInt32(GetSingleByteArray(buff3, i, dataFormat), 0).ToString() + " ";
                        }
                        Current_time = System.DateTime.Now;
                        SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
                        SetMsg(dwordvalue + " ");
                        SetMsg("\r\n");
                    }
                    else
                    {
                        SetMsg("读取失败,请检查地址、类型及连接状态");
                        SetMsg("\r\n");
                    }
                    break;
                case VarType.Int:
                    buff3 = SwapAB(buff3);
                    string intvalue = string.Empty;
                    if (buff3 != null && buff3.Length == numberOfPoints * 2)
                    {
                        for (int i = 0; i < buff3.Length; i += 2)
                        {
                            //intvalue += BitConverter.ToInt16(GetIntByteArray(buff3, i, dataFormat), 0).ToString() + " ";
                            intvalue += BitConverter.ToInt16(buff3.Skip(i).Take(2).ToArray(), 0).ToString() + " ";
                        }
                        Current_time = System.DateTime.Now;
                        SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
                        SetMsg(intvalue + " ");
                        SetMsg("\r\n");
                    }
                    else
                    {
                        SetMsg("读取失败,请检查地址、类型及连接状态");
                        SetMsg("\r\n");
                    }
                    break;
                case VarType.DInt:
                    buff3 = SwapABCD(buff3);
                    string dintvalue = string.Empty;
                    if (buff3 != null && buff3.Length == numberOfPoints * 4)
                    {
                        for (int i = 0; i < buff3.Length; i += 4)
                        {
                            dintvalue += BitConverter.ToInt32(GetSingleByteArray(buff3, i, dataFormat), 0).ToString() + " ";
                        }
                        Current_time = System.DateTime.Now;
                        SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
                        SetMsg(dintvalue + " ");
                        SetMsg("\r\n");
                    }
                    else
                    {
                        SetMsg("读取失败,请检查地址、类型及连接状态");
                        SetMsg("\r\n");
                    }
                    break;
                case VarType.Real:
                    buff3 = SwapABCD(buff3);
                    string floatvalue = string.Empty;
                    if (buff3 != null && buff3.Length == numberOfPoints * 4)
                    {
                        for (int i = 0; i < buff3.Length; i += 4)
                        {
                            floatvalue += BitConverter.ToSingle(GetSingleByteArray(buff3, i, dataFormat), 0).ToString() + " ";
                        }
                        Current_time = System.DateTime.Now;
                        SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " 读取成功,读取值:"));
                        SetMsg(floatvalue + " ");
                        SetMsg("\r\n");
                    }
                    else
                    {
                        SetMsg("读取失败,请检查地址、类型及连接状态");
                        SetMsg("\r\n");
                    }
                    break;
                case VarType.Bit:
                case VarType.String:
                case VarType.Byte:
                case VarType.Timer:
                case VarType.Counter:
                    MessageBox.Show("读取失败,变量类型不支持");
                    break;
            }
        }

        private void ResolutionReply(byte[] buff, byte f)//解析写数据回复
        {
            byte f1 = buff[1];
            string res = "false";
            if (f == 0x05)
            {
                if (buff[4] == 0xff)
                {
                    res = "true";
                }
                else
                {
                    res = "false";
                }
            }
            else if (f == 0x06)
            {
                //byte[] buff3 = { buff[5], buff[4], 0, 0 };
                //res = (BitConverter.ToInt32(buff3, 0)).ToString();

                switch (vartype)
                {
                    case VarType.Word:
                        byte[] UshortBuff = { buff[5], buff[4] };
                        res = (BitConverter.ToUInt16(UshortBuff, 0)).ToString();
                        break;
                    case VarType.Int:
                        byte[] ShortBuff = { buff[5], buff[4] };
                        res = (BitConverter.ToInt16(ShortBuff, 0)).ToString();
                        break;
                    case VarType.DWord:
                    case VarType.DInt:
                    case VarType.Real:
                    case VarType.Bit:
                    case VarType.String:
                    case VarType.Byte:
                    case VarType.Timer:
                    case VarType.Counter:
                        break;
                }
            }
            else if (f == 0x0f)
            {
                res = "";
                byte[] intBuff = { 0, 0, 0, 0 };
                intBuff = BitConverter.GetBytes(numberOfPoints);
                if (buff[4] == intBuff[1] && buff[5] == intBuff[0] && f1 == f)
                {
                    string[] strarr = InPutstr.Split(' ');
                    for (int i = 0; i < strarr.Length; i++)
                    {
                        if (i < strarr.Length)
                        {
                            if (strarr[i] == "0")
                            {
                                strarr[i] = "fasle";
                            }
                            else
                            {
                                strarr[i] = "true";
                            }
                            res += strarr[i] + " ";
                        }
                    }
                }
                else
                {
                    f1 = (byte)(f + 1);
                }
            }
            else if (f == 0x10)
            {
                res = "";
                byte[] intBuff = { 0, 0, 0, 0 };
                switch (vartype)
                {
                    case VarType.Word:
                        intBuff = BitConverter.GetBytes(numberOfPoints);
                        break;
                    case VarType.Int:
                        intBuff = BitConverter.GetBytes(numberOfPoints);
                        break;
                    case VarType.DWord:
                        intBuff = BitConverter.GetBytes(numberOfPoints * 2);
                        break;
                    case VarType.DInt:
                        intBuff = BitConverter.GetBytes(numberOfPoints * 2);
                        break;
                    case VarType.Real:
                        intBuff = BitConverter.GetBytes(numberOfPoints * 2);
                        break;
                    case VarType.Bit:
                    case VarType.String:
                    case VarType.Byte:
                    case VarType.Timer:
                    case VarType.Counter:
                        break;
                }
                if (buff[4] == intBuff[1] && buff[5] == intBuff[0] && f1 == f)
                {
                    res = InPutstr;
                }
                else
                {
                    f1 = (byte)(f + 1);
                }
            }
            Current_time = System.DateTime.Now;
            SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " "));
            SetMsg(f1 == f ? "写入成功,写入值:" + res : "写入失败");
            SetMsg("\r\n");
        }


        /// <summary>
        /// 串口发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            String Str = txt_data.Text.ToString();//获取发送文本框里面的数据
            try
            {
                if (Str.Length > 0)
                {
                    if (checkBox2.Checked)//16进制发送
                    {
                        byte[] byt = strToToHexByte(Str);
                        port.Write(byt, 0, byt.Length);
                    }
                    else
                    {
                        port.Write(Str);//串口发送数据
                    }
                }
            }
            catch (Exception) { }
        }

        /// <summary>
        /// 串口接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int len = port.BytesToRead;//获取可以读取的字节数
            byte[] buff = new byte[len];//创建缓存数据数组
            port.Read(buff, 0, len);//把数据读取到buff数组
            if (buff.Length > 1 && buff[1] != 0x81 && buff[1] != 0x83)
            {
                if (functionCode != null)
                {
                    switch (functionCode)
                    {
                        case "01 Read Coils"://读取输出线圈
                            byte[] buff0 = buff.Skip(3).Take(buff[2]).ToArray();
                            ResolutionCoils(buff0);
                            break;
                        case "02 Read DisCrete Inputs"://读取输入线圈/离散量线圈
                            byte[] buff1 = buff.Skip(3).Take(buff[2]).ToArray();
                            ResolutionCoils(buff1);
                            break;
                        case "03 Read Holding Registers"://读取保持寄存器
                            byte[] buff2 = buff.Skip(3).Take(buff[2]).ToArray();
                            ResolutionRegisters(buff2);
                            break;
                        case "04 Read Input Registers"://读取输入寄存器
                            byte[] buff3 = buff.Skip(3).Take(buff[2]).ToArray();
                            ResolutionRegisters(buff3);
                            break;
                        case "05 Write Single Coil"://写单个线圈
                            ResolutionReply(buff, 05);
                            break;
                        case "06 Write Single Registers"://写单个保持寄存器
                            ResolutionReply(buff, 06);
                            break;
                        case "0F Write Multiple Coils"://写一组线圈
                            ResolutionReply(buff, 0x0F);
                            break;
                        case "10 Write Multiple Registers"://写一组保持寄存器
                            ResolutionReply(buff, 0x10);
                            break;
                    }
                }
            }
            else
            {
                if (buff.Length > 2)
                {
                    Current_time = System.DateTime.Now;
                    SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " "));
                    SetMsg("异常应答,异常代码:" + buff[2].ToString() + " ");
                    SetMsg("\r\n");
                }
            }


            //Buff = buff;
            //SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " "));
            //Invoke((new Action(() =>
            //{//C# 3.0以后代替委托的新方法
            //    if (checkBox1.Checked)//16进制显示
            //    {
            //        SetMsg(byteToHexStr(buff) + " ");//对话框追加显示数据

            //    }
            //    else
            //    {
            //        SetMsg(Encoding.Default.GetString(buff) + " ");//对话框追加显示数据
            //    }
            //})));
            //SetMsg("\r\n");
            //Buff = buff.Take(len - 2).ToArray();
            //UintToHex(ref L, ref H, GetCRC16(Buff));

            //List<byte> frameBytes = new List<byte>();
            //for (int i = 0; i < Buff.Length; i++)
            //{
            //    frameBytes.Add(Buff[i]);
            //}
            //frameBytes.Add(L);
            //frameBytes.Add(H);
            //Buff = frameBytes.ToArray();//list转byte[]
            // List<byte> b=transByte.ToList();//byte[]转list
            //SetMsg(byteToHexStr(Buff) + " ");//对话框追加显示数据
            //SetMsg("\r\n");
        }
        byte L;
        byte H;
        public static void UintToHex(ref byte L, ref byte H, uint Val)
        {
            L = (byte)(Val & (uint)byte.MaxValue);
            H = (byte)(Val >> 8);
        }
        public static void UshortToHex(ref byte L, ref byte H, ushort Val)
        {
            L = (byte)((uint)Val & (uint)byte.MaxValue);
            H = (byte)((uint)Val >> 8);
        }
        /// <字节数组转16进制字符串>
        /// <param name="bytes"></param>
        /// <returns> String 16进制显示形式</returns>
        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            try
            {
                if (bytes != null)
                {
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        returnStr += bytes[i].ToString("X2");
                        returnStr += " ";//两个16进制用空格隔开,方便看数据
                    }
                }
                return returnStr;
            }
            catch (Exception)
            {
                return returnStr;
            }
        }
        /// <字符串转16进制格式,不够自动前面补零>
        /// 
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        private static byte[] strToToHexByte(String hexString)
        {
            int i;
            hexString = hexString.Replace(" ", "");//清除空格
            if ((hexString.Length % 2) != 0)//奇数个
            {
                byte[] returnBytes = new byte[(hexString.Length + 1) / 2];
                try
                {
                    for (i = 0; i < (hexString.Length - 1) / 2; i++)
                    {
                        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
                    }
                    returnBytes[returnBytes.Length - 1] = Convert.ToByte(hexString.Substring(hexString.Length - 1, 1).PadLeft(2, '0'), 16);
                }
                catch
                {
                    MessageBox.Show("含有非16进制字符", "提示");
                    return null;
                }
                return returnBytes;
            }
            else
            {
                byte[] returnBytes = new byte[(hexString.Length) / 2];
                try
                {
                    for (i = 0; i < returnBytes.Length; i++)
                    {
                        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
                    }
                }
                catch
                {
                    MessageBox.Show("含有非16进制字符", "提示");
                    return null;
                }
                return returnBytes;
            }
        }
        /// <summary>
        /// ABABABABAB……转换为BABABABABA
        /// </summary>
        /// <param name="byteArr"></param>
        /// <returns></returns>
        private byte[] SwapAB(byte[] byteArr)
        {
            if (byteArr.Length % 2 == 0)
            {
                byte tmpe;
                for (int i = 0; i < byteArr.Length; i += 2)
                {
                    tmpe = byteArr[i];
                    byteArr[i] = byteArr[i + 1];
                    byteArr[i + 1] = tmpe;
                }
                return byteArr;
            }
            else
            {
                MessageBox.Show("数据长度错误");
                return null;
            }
        }
        /// <summary>
        /// ABCDABCDABCDABCDABCD……转换为DCBADCBADCBADCBADCBA
        /// </summary>
        /// <param name="byteArr"></param>
        /// <returns></returns>
        private byte[] SwapABCD(byte[] byteArr)
        {
            byte tmpe1;
            byte tmpe2;
            if (byteArr.Length % 4 == 0)
            {
                for (int i = 0; i < byteArr.Length; i += 4)
                {
                    tmpe1 = byteArr[i];
                    tmpe2 = byteArr[i + 1];
                    byteArr[i] = byteArr[i + 3];
                    byteArr[i + 1] = byteArr[i + 2];
                    byteArr[i + 2] = tmpe2;
                    byteArr[i + 3] = tmpe1;
                }
                return byteArr;
            }
            else
            {
                MessageBox.Show("数据长度错误");
                return null;
            }
        }

        #region 双字节顺序转换
        /// <summary>
        /// 双字节顺序转换:1为AB,2为BA
        /// </summary>
        /// <param name="byteArr"></param>
        /// <param name="start"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private byte[] GetIntByteArray(byte[] byteArr, int start, DataFormat type)
        {
            byte[] Res = new byte[2];
            if (byteArr != null && byteArr.Length >= start + 2)
            {
                for (int i = 0; i < 2; i++)
                {
                    Res[i] = byteArr[i + start];
                }
                byte[] Res1 = new byte[2];
                switch (type)
                {
                    case DataFormat.ABCD:
                    case DataFormat.CDAB:
                        Res1 = Res;
                        break;
                    case DataFormat.BADC:
                    case DataFormat.DCBA:
                        Res1[1] = Res[0];
                        Res1[0] = Res[1];
                        break;
                    default:
                        break;
                }
                return Res1;
            }
            return Res;
        }
        #endregion

        #region 四字节顺序转换

        /// <summary>
        /// 四字节顺序转换:1为ABCD,2为BADC,3为CDAB,4为 DCBA
        /// </summary>
        /// <param name="byteArr"></param>
        /// <param name="start"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private byte[] GetSingleByteArray(byte[] byteArr, int start, DataFormat type)
        {
            byte[] Res = new byte[4];
            if (byteArr != null && byteArr.Length >= start + 4)
            {
                for (int i = 0; i < 4; i++)
                {
                    Res[i] = byteArr[i + start];
                }
                byte[] Res1 = new byte[4];
                switch (type)
                {
                    case DataFormat.ABCD:
                        Res1 = Res;
                        break;
                    case DataFormat.BADC:
                        Res1[0] = Res[1];
                        Res1[1] = Res[0];
                        Res1[2] = Res[3];
                        Res1[3] = Res[2];
                        break;
                    case DataFormat.CDAB:
                        Res1[0] = Res[2];
                        Res1[1] = Res[3];
                        Res1[2] = Res[0];
                        Res1[3] = Res[1];
                        break;
                    case DataFormat.DCBA:
                        Res1[0] = Res[3];
                        Res1[1] = Res[2];
                        Res1[2] = Res[1];
                        Res1[3] = Res[0];
                        break;
                    default:
                        break;
                }
                return Res1;
            }
            return Res;
        }
        #endregion
        #region CRC校验
        public uint GetCRC16(byte[] buffer)
        {
            int length = buffer.Length;
            byte data;
            uint crc = 0xFFFF; //初始值(16位举个例子0xFFFF,8位0xFF)
            int i;
            for (int j = 0; j < length; j++)
            {
                data = buffer[j];
                data = (byte)Reverse8(data); //输入是否反转,如果不需要则这句注释掉;
                crc = (uint)(crc ^ (data << 8)); //32位左移24位,16位左移8位,8位左移0位;
                for (i = 0; i < 8; i++)
                {
                    if ((crc & 0x8000) == 0x8000)//16位 0x8000  8位 0x80
                    {
                        crc = (crc << 1) ^ 0x8005;//多项式,没什么好说的;
                    }
                    else
                    {
                        crc <<= 1;
                    }
                }
            }
            crc = Reverse16(crc);//输出是否需要反转,如果不需要则注释掉这句话,注意如果是16位则调用Reverse16(crc),8位调用Reverse8(crc)
            crc = crc ^ 0x0000;// xor 异或值(与上面初始值类似,16位 0x0000  8位 0x00;
            return crc;
        }
        public uint GetCRC32(byte[] buffer)
        {
            int length = buffer.Length;
            byte data;
            uint crc = 0xFFFFFFFF; //初始值(16位举个例子0xFFFF,8位0xFF)
            int i;
            for (int j = 0; j < length; j++)
            {
                data = buffer[j];
                data = (byte)Reverse8(data); //输入是否反转,如果不需要则这句注释掉;
                crc = (uint)(crc ^ (data << 24)); //32位左移24位,16位左移8位,8位左移0位;
                for (i = 0; i < 8; i++)
                {
                    if ((crc & 0x80000000) == 0x80000000)//16位 0x8000  8位 0x80
                    {
                        crc = (crc << 1) ^ 0x04C11DB7;//多项式,没什么好说的;
                    }
                    else
                    {
                        crc <<= 1;
                    }
                }
            }
            crc = Reverse32(crc);//输出是否需要反转,如果不需要则注释掉这句话,注意如果是16位则调用Reverse16(crc),8位调用Reverse8(crc)
            crc = crc ^ 0x00000000;// xor 异或值(与上面初始值类似,16位 0x0000  8位 0x00;
            return crc;
        }
        private uint Reverse32(uint data)
        {
            byte i;
            uint temp = 0;
            for (i = 0; i < 32; i++)
            {
                temp |= ((data >> i) & 0x01) << (31 - i);
            }
            return temp;
        }

        private uint Reverse16(uint data)
        {
            byte i;
            uint temp = 0;
            for (i = 0; i < 16; i++)
            {
                temp |= ((data >> i) & 0x01) << (15 - i);
            }
            return temp;
        }

        private byte Reverse8(byte data)
        {
            byte i;
            byte temp = 0;
            for (i = 0; i < 8; i++)
            {
                temp = (byte)(temp | (((data >> i) & 0x01) << (7 - i)));
            }
            return temp;
        }
        #endregion

        private void cmb_DataFormat_SelectedIndexChanged(object sender, EventArgs e)
        {
            dataFormat = (DataFormat)Enum.Parse(typeof(DataFormat), cmb_DataFormat.SelectedItem.ToString(), false);
        }

        private void cmb_VarType_SelectedIndexChanged(object sender, EventArgs e)
        {
            vartype = (VarType)Enum.Parse(typeof(VarType), cmb_VarType.SelectedItem.ToString(), false);
        }

        private void rb_CheckedChanged(object sender, EventArgs e)
        {
            gbRTU.Enabled = rbRTU.Checked;
            gbTCP.Enabled = rbTCP.Checked;
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (btnOpen.Text == "打开连接")
            {//如果按钮显示的是打开串口
                try
                {
                    //防止意外错误
                    if (!InitPortParameter())
                    {
                        return;
                    }
                    //创建客户端Socket,获得远程ip和端口号
                    socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    IPAddress ip = IPAddress.Parse(IP);
                    IPEndPoint point = new IPEndPoint(ip, Port);
                    socketSend.Connect(point);
                    SetMsg("连接成功!");
                    SetMsg("\r\n");
                    IsOpen = true;
                    btnOpen.Text = "断开连接";
                    button1.Enabled = true;
                    //开启新的线程,不停的接收服务器发来的消息
                    Thread c_thread = new Thread(Received);
                    c_thread.IsBackground = true;
                    c_thread.Start();
                }
                catch (Exception)
                {
                    IsOpen = false;
                    SetMsg("IP或者端口号错误...");
                    SetMsg("\r\n");
                }
            }
            else
            {
                try
                {//防止意外错误
                    socketSend.Close();//关闭
                    button1.Enabled = false;
                    btnOpen.Text = "打开连接";//按钮显示打开
                    SetMsg("断开连接成功!");
                    SetMsg("\r\n");
                }
                catch (Exception) { }
                
            }
        }
        void send(string msg)
        {
            try
            {
                byte[] buffer = new byte[1024 * 1024 * 3];
                buffer = Encoding.UTF8.GetBytes(msg);
                socketSend.Send(buffer);
            }
            catch { }
        }
        /// <summary>
        /// 接收服务端返回的消息
        /// </summary>
        void Received()
        {
            while (true)
            {
                try
                {
                    byte[] buff = new byte[1024 * 1024 * 3];
                    //实际接收到的有效字节数
                    int len = socketSend.Receive(buff);
                    if (len == 0)
                    {
                        break;
                    }
                    //string str = Encoding.UTF8.GetString(buff, 0, len);
                    //SetMsg(socketSend.RemoteEndPoint + ":" + str);
                    //SetMsg("\r\n");
                    if (buff.Length > 7 && buff[7] != 0x81 && buff[7] != 0x83)
                    {
                        if (functionCode != null)
                        {
                            switch (functionCode)
                            {
                                case "01 Read Coils"://读取输出线圈
                                    byte[] buff0 = buff.Skip(9).Take(buff[8]).ToArray();
                                    ResolutionCoils(buff0);
                                    break;
                                case "02 Read DisCrete Inputs"://读取输入线圈/离散量线圈
                                    byte[] buff1 = buff.Skip(9).Take(buff[8]).ToArray();
                                    ResolutionCoils(buff1);
                                    break;
                                case "03 Read Holding Registers"://读取保持寄存器
                                    byte[] buff2 = buff.Skip(9).Take(buff[8]).ToArray();
                                    ResolutionRegisters(buff2);
                                    break;
                                case "04 Read Input Registers"://读取输入寄存器
                                    byte[] buff3 = buff.Skip(9).Take(buff[8]).ToArray();
                                    ResolutionRegisters(buff3);
                                    break;
                                case "05 Write Single Coil"://写单个线圈
                                    byte[] buff4 = buff.Skip(6).ToArray();
                                    ResolutionReply(buff4, 05);
                                    break;
                                case "06 Write Single Registers"://写单个保持寄存器
                                    byte[] buff5 = buff.Skip(6).ToArray();
                                    ResolutionReply(buff5, 06);
                                    break;
                                case "0F Write Multiple Coils"://写一组线圈
                                    byte[] buff6 = buff.Skip(6).ToArray();
                                    ResolutionReply(buff6, 0x0F);
                                    break;
                                case "10 Write Multiple Registers"://写一组保持寄存器
                                    byte[] buff7 = buff.Skip(6).ToArray();
                                    ResolutionReply(buff7, 0x10);
                                    break;
                            }
                        }
                    }
                    else
                    {
                        if (buff.Length > 8)
                        {
                            Current_time = System.DateTime.Now;
                            SetMsg("[" + Current_time.ToString("yyyy-MM-dd HH:mm:ss" + "]" + " "));
                            SetMsg("异常应答,异常代码:" + buff[8].ToString() + " ");
                            SetMsg("\r\n");
                        }
                    }
                }
                catch { }
            }
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值