2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Lisää aika (ajastin)
Koska tuulen nopeus ja suunta on päivitettävä automaattisesti
①Palvelinyhteyspainike
- // 连接按钮
- private void button1_Click(object sender, EventArgs e)
- {
- if (button1.Text =="连接")
- {
- ConnectSocke();// 连接服务器
- }
- else
- {
- CloseSocket(); // 关闭服务器
- }
- }
- Socket soc;
- // 连接方法
- void ConnectSocke()
- {
- try
- {
- // 创建socket对象
- soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 套接字对象
- // 连接服务器ip地址,端口号
- soc.Connect(this.textBox1.Text, int.Parse(this.textBox2.Text));
- button1.Text = "关闭";
- textBox1.Enabled = false;
- textBox2.Enabled = false;
- }
- catch (Exception ex)
- {
- MessageBox.Show("串口服务器连接失败");
- }
- }
- // 关闭方法
- void CloseSocket()
- {
- if (soc!=null && soc.Connected)
- {
- soc.Close();
- }
- button1.Text = "连接";
- this.textBox1.Enabled = true;
- this.textBox2.Enabled = true;
- }
- // 连接方法
- void ConnectSocke()
- {
- try
- {
- // 创建socket对象
- soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 套接字对象
-
- // 连接服务器ip地址,端口号
- soc.Connect(this.textBox1.Text, int.Parse(this.textBox2.Text));
- button1.Text = "关闭";
- textBox1.Enabled = false;
- textBox2.Enabled = false;
- }
- catch (Exception ex)
- {
-
- MessageBox.Show("串口服务器连接失败");
- }
- }
Määritä, onko button1.text "yhdistetty", suorita palvelimen suorittaminen ConnectSocke();
Yhteystapa: käytä try catch poikkeuskäsittelyä, luo globaali muuttuja Socket soc, luo objektin yhteys ip-portin numeroksi, muuta textbox1.text suljetuksi, textBox1.Enabled=false, tee syöttöruutuun syöttämätön, catch poikkeuskäsittely määrittää koodin kokeile Ilmoita virheestä Jos virhe ilmoitetaan, suorita catch-koodi?
Katkaise yhteys: Määritä, onko soc tyhjä vai onko yhteys suljettu soc.Close();, aseta button1.text="Yhdistä" niin, että tekstilaatikko1 ja 2 voivat peruuttaa
- // 发送按钮
- private void button2_Click(object sender, EventArgs e)
- {
- string sendS = this.textBox3.Text.Trim();// 发送字符串
- if (soc == null || !soc.Connected)
- {
- MessageBox.Show("服务器没连接");
- return;
- }
- if (string.IsNullOrEmpty(sendS))
- {
- MessageBox.Show("指令不能为空");
- return;
- }
-
- //1 把字符串转成字符数组
- byte[] data = StringToHexByte(sendS);
- //2 计算校检码
- byte[] b1 = CRCCalc(data);
- //3 合并字节数组和校检码数组
- data = data.Concat(b1).ToArray();
-
- button2.Enabled = false;
- Task.Run(() =>
- {
- //4 发起请求帧
- soc.Send(data);// 发消息 请求 温度请求帧data = []
-
- Thread.Sleep(1000);// 休眠1秒
-
- //5 接受数据 // 接收温度
- byte[] rec = new byte[1024]; // rec =
- int length = soc.Receive(rec);
-
- // 6 解析数据并且展示数据 把字节数组转成字符串
- string s = ByteToString(rec, length);
- s += "rn";
- int temp = (rec[3] * 256 + rec[4]) / 10;// 温度
- this.richTextBox1.Invoke((Action)(() =>
- {
- richTextBox1.AppendText(s);// 响应帧
- richTextBox1.AppendText($"当前温度温度为:{temp}摄氏度,时间为:{DateTime.Now.ToString()}rn");
- button2.Enabled = true;
- }));
-
- });
- }
- string ByteToString(byte[] b1,int l)
- {
- StringBuilder sb = new StringBuilder();// 可变字符串
- for (int i = 0; i < l; i++)
- {
- sb.Append(b1[i].ToString("X2")+" ");
- }
-
- return sb.ToString();
- }
-
-
- // 字符串转成字符数组
- byte[] StringToHexByte(string s)
- {
- string[] ss = s.Split(' ');
- byte[] result = new byte[ss.Length];// 字节数组
- for (int i = 0; i < ss.Length; i++)
- {
- result[i] = Convert.ToByte(ss[i], 16);//转成16进制字节
- }
- return result;
- }
- // 校检方法
- public static byte[] CRCCalc(byte[] data)
- {
- //crc计算赋初始值
- int crc = 0xffff;
- for (int i = 0; i < data.Length; i++)
- {
- //XOR
- //(1) 0^0=0,0^1=1 0异或任何数=任何数
- //(2) 1 ^ 0 = 1,1 ^ 1 = 0 1异或任何数-任何数取反
- //(3) 1 ^ 1 = 0,0 ^ 0 = 0 任何数异或自己=把自己置0
- //异或操作符是^。异或的特点是相同为false,不同为true。
- crc = crc ^ data[i]; //和^表示按位异或运算。
- //0x0fff ^ 0x01 Console.WriteLine(result.ToString("X"));
- // 输出结果为4094,即十六进制数1001
- for (int j = 0; j < 8; j++)
- {
- int temp;
- temp = crc & 1; // & 运算符(与) 1 & 0 为 0 ;0 & 0 为0;1 & 1 为1
-
- //右移 (>>) 将第一个操作数向右移动第二个操作数所指定的位数,空出的位置补0。右移相当于整除. 右移一位相当于除以2;右移两位相当于除以4;右移三位相当于除以8。
- //int i = 7;
- //int j = 2;
- //Console.WriteLine(i >> j); //输出结果为1
- crc = crc >> 1;
- crc = crc & 0x7fff;
- if (temp == 1)
- {
- crc = crc ^ 0xa001;
- }
- crc = crc & 0xffff;
- }
- }
- //CRC寄存器的高低位进行互换
- byte[] crc16 = new byte[2];
- //CRC寄存器的高8位变成低8位,
- crc16[1] = (byte)((crc >> 8) & 0xff);
- //CRC寄存器的低8位变成高8位
- crc16[0] = (byte)(crc & 0xff);
- return crc16;
- }
- // 刷新按钮
- private void button3_Click(object sender, EventArgs e)
- {
- Refresh1();
- }
- void Refresh1()
- {
- if (soc == null || !soc.Connected)
- {
- MessageBox.Show("没连接");
- return;
- }
- Task.Run(() =>
- {
- // 请求帧的组织
- byte[] bs = new byte[] {0x01,0x03,0x00,0x00,0x00,0x02};// 风速和风向请求放在一起
-
- // 数据和校检
- bs = bs.Concat(CRCCalc(bs)).ToArray();
-
- soc.Send(bs);// 发送
-
- Thread.Sleep(1000);
-
- // 接受数据表
- byte[] rec = new byte[1024];
- int length = soc.Receive(rec);
-
- double wind = (rec[3] * 256 + rec[4]) * 0.01;
- double dir = (rec[5] * 256 + rec[6]);
- this.Invoke((Action)(() =>
- {
- this.textBox4.Text = wind + "m/s";
- this.textBox5.Text = dir + "";
- }));
-
-
- });
- }
-
- // 定时器
- private void timer1_Tick(object sender, EventArgs e)
- {
- if (checkBox1.Checked)// 复选框被选中
- {
- Refresh1();
- }
-
- }
- }
-
- }