SerialportToTCP② 全

效果补全(代码):

namespace SerialportToTCP
{public partial class Form1 : Form{IniHelper Ini;string[] botelvs = new string[] { "1200", "4800", "9600", "13200" };public Form1(){InitializeComponent();//1 读取配置文件string dirPath = Path.Combine(Application.StartupPath, "File");// debug/filestring filePath = Path.Combine(dirPath, "Setting.ini");// debug / file/setting.iniIni = new IniHelper(filePath); //创建读取对象// 添加串口comboBox1.Items.AddRange(SerialPort.GetPortNames());// 获取所有串口 拼接在下拉框的items中comboBox2.Items.AddRange(botelvs);// 添加波特率数组comboBox2.Items.Add("自定义");//添加一个comboBox3.Items.AddRange(new string[] { "5", "6", "7", "8" });comboBox4.Items.AddRange(new string[] { "无", "奇校检", "偶校检" });comboBox5.Items.AddRange(new string[] { "无", "1", "2", "1.5" });//2开始处理串口接受数据事件//处理串口的数据this.serialPort1.DataReceived += SerialPort1_DataReceived;//3 处理界面显示默认值 也就是从ini文件读取数据readSetting();//4 开始串口通信startChuanKou();//5 开始网口通信startTCP();}//开始搭建TCP服务器TcpListener listen;List<TcpClient> lists = new List<TcpClient>();//存放所有的客户端void startTCP(){if(!int.TryParse(textBox3.Text,out int port) || port < 1 || port >65563){MessageBox.Show("请输入正确的端口号");}//开启服务器 接受客户端try{listen = new TcpListener(System.Net.IPAddress.Any, port);listen.Start(100); //开始监听panel2.BackColor = Color.Green;//把多个客户端接受到数组里面 异步接受new Task(() => {try{while (true){//接收客户端TcpClient c1 = listen.AcceptTcpClient();// 把客户端添加到数组里面 群发需要lists.Add(c1);//接收客户端发来的消息tcpReceive(c1);}}catch{MessageBox.Show("TCP服务器关闭");}}).Start();}catch{MessageBox.Show("TCP启动失败");//把tcp关闭等操作foreach (var item in lists){item.Close(); //关闭所有的客户端}listen.Stop();panel2.BackColor = Color.Gray;}}//tcp 接收数据void tcpReceive(TcpClient c1){new Task(() =>{NetworkStream stream = c1.GetStream();try{while (c1.Connected) //客户端连接的时候{byte[] bs = new byte[1024];int length =  stream.Read(bs, 0, bs.Length);if (length == 0) throw new Exception(); // 客户端断了//接收到数据亮灯tcpLiangDeng();//把数据转给串口if (!serialPort1.IsOpen){MessageBox.Show("串口关闭");break;}//把数据转给串口 serialPort1发送数据, com6能接受到消息,serialPort1.Write(bs, 0, length);}}catch{c1.Close();lists.Remove(c1);}}).Start();}//tcp 接收到数据亮灯的方法async void tcpLiangDeng(){this.Invoke((Action)(() =>{textBox2.Text = (int.Parse(textBox2.Text) + 1).ToString();//亮灯panel4.BackColor = Color.Green;}));//过一段时间await Task.Delay(70);this.Invoke((Action)(() =>{//关灯panel4.BackColor = Color.Gray;}));}void startChuanKou(){// 配置串口对象try{this.serialPort1.PortName = comboBox1.Text;//配置串口名称this.serialPort1.BaudRate = int.Parse(comboBox2.Text); //波特率this.serialPort1.DataBits = int.Parse( comboBox3.Text);this.serialPort1.StopBits = (StopBits)comboBox5.SelectedIndex;// 正常赋值 StopBits.None 枚举值。正好对应数据0this.serialPort1.Parity = (Parity)comboBox4.SelectedIndex; // this.serialPort1.Open();//亮灯this.panel1.BackColor = Color.Green;}catch{MessageBox.Show("打开串口失败");//停止串口if(serialPort1.IsOpen) serialPort1.Close();//灭灯this.panel1.BackColor = Color.Gray;}}void readSetting(){//先配置串口comboBox1.SelectedItem = Ini.Read("Serialport", "name", "");string botelv = Ini.Read("Serialport", "botelv", "9601");int botelvIndex = Array.IndexOf(botelvs, botelv);// 获取botelv在数组里面的索引值if (botelvIndex != -1) // 证明波特率在数组里面{comboBox2.SelectedIndex= botelvIndex;comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;}else{//波特率在数组里面 自定义波特率情况comboBox2.DropDownStyle = ComboBoxStyle.DropDown; //可编辑的下拉框//DropDownList 不可编辑的下拉框comboBox2.Text = botelv;}//处理数据位comboBox3.SelectedItem = Ini.Read("Serialport", "databit", "8");//处理奇偶校检comboBox4.SelectedIndex = Ini.Read("Serialport", "parity", 0);comboBox5.SelectedIndex = Ini.Read("Serialport", "stopbit", 0);comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;comboBox3.DropDownStyle = ComboBoxStyle.DropDownList;comboBox4.DropDownStyle = ComboBoxStyle.DropDownList;comboBox5.DropDownStyle = ComboBoxStyle.DropDownList;//网口数据的读取textBox3.Text = Ini.Read("NetWork", "port", "8080");if( Ini.Read("NetWork", "heartOn", false)){radioButton1.Checked = true;}else{radioButton2.Checked = true;}textBox4.Text= Ini.Read("NetWork", "heartTime", "60000");// 心跳间隔  textBox5.Text = Ini.Read("NetWork", "heartData", ""); //心跳包数据checkBox1.Checked = Ini.Read("NetWork", "heartHex", false);//s是否采用16进制}// 接受串口传递数据private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e){byte[] bs = new byte[1024]; //定义一个字节数组int count = serialPort1.Read(bs, 0, bs.Length); //读取数据到字节数组里面if (count == 0){//关闭串口//停止串口if (serialPort1.IsOpen) serialPort1.Close();//灭灯this.panel1.BackColor = Color.Gray;}//1 接收到1条串口数据 需要panel3亮一次 封装一个方法控制效果jieShouDaoChuankou();//2 转发给所有客户端数据 串口转网口就是把串口数据通过网络转给其他客户端 foreach (var item in lists){item.GetStream().Write(bs, 0, bs.Length);}}async void jieShouDaoChuankou(){this.Invoke((Action)(() =>{textBox1.Text = (int.Parse(textBox1.Text)+1).ToString();//亮灯panel3.BackColor = Color.Green;}));//过一段时间await Task.Delay(70);this.Invoke((Action)(() =>{//关灯panel3.BackColor = Color.Gray;}));}//波特率下拉框触发变化的时候调用private void comboBox2_SelectedIndexChanged(object sender, EventArgs e){if (comboBox2.SelectedItem.ToString() == "自定义"){//切换到自定义选项上comboBox2.DropDownStyle= ComboBoxStyle.DropDown;}else{comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;}}//选中心跳开关为开的时候private void radioButton1_CheckedChanged(object sender, EventArgs e){//MessageBox.Show(textBox4.Text + "????/");if (radioButton1.Checked){//选中心跳timer1.Interval = string.IsNullOrEmpty(textBox4.Text) ? 2000 : int.Parse(textBox4.Text); timer1.Tick += Timer1_Tick;timer1.Start();}}//定时器函数private void Timer1_Tick(object sender, EventArgs e){//定时发送数据string data = textBox5.Text; //心跳数据 2选中hex证明把2转成16进制,byte[] buffer;if (checkBox1.Checked == true){//需要发16进制的心跳string[] ds = data.Split(' '); //把2按照空格符号分割成数组结构[2]buffer = new byte[ds.Length]; //buffer数组长度就是ds的长度for (int i = 0; i < ds.Length; i++){//System.Globalization.NumberStyles.HexNumber 转成16进制数//把ds[i]转成16进制buffer[i] = byte.Parse(ds[i], System.Globalization.NumberStyles.HexNumber);}}else{//不采用16进制的心跳包buffer = Encoding.UTF8.GetBytes(data);}foreach (var item in lists){item.GetStream().Write(buffer, 0, buffer.Length);}}//关闭心跳private void radioButton2_CheckedChanged(object sender, EventArgs e){timer1.Stop();}//重启private void button1_Click(object sender, EventArgs e){//停掉tcpforeach (var item in lists){item.Close(); //关闭所有的客户端}listen.Stop();panel2.BackColor = Color.Gray;//停掉串口if (serialPort1.IsOpen) serialPort1.Close();//灭灯this.panel1.BackColor = Color.Gray;//开启tcpstartTCP();//开启串口startChuanKou();}//保存private void button2_Click(object sender, EventArgs e){//Serialport", "databit", "8");Ini.Write("Serialport", "name", comboBox1.Text);Ini.Write("Serialport", "botelv", comboBox2.Text);Ini.Write("Serialport", "stopbit", comboBox5.SelectedIndex);Ini.Write("Serialport", "parity", comboBox4.SelectedIndex);Ini.Write("Serialport", "databit", comboBox3.Text);//5 6 7 8 Ini.Write("NetWork", "port", textBox3.Text);Ini.Write("NetWork", "heartOn",radioButton1.Checked);Ini.Write("NetWork", "heartTime", textBox4.Text);Ini.Write("NetWork", "heartData", textBox5.Text);Ini.Write("NetWork", "heartHex", checkBox1.Checked);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/38877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch:Painless scripting 语言(一)

Painless 是一种高性能、安全的脚本语言&#xff0c;专为 Elasticsearch 设计。你可以使用 Painless 在 Elasticsearch 支持脚本的任何地方安全地编写内联和存储脚本。 Painless 提供众多功能&#xff0c;这些功能围绕以下核心原则&#xff1a; 安全性&#xff1a;确保集群的…

安卓gdb 建立链接

adbshell gdbserver :1234 testdcam --sensor 0 --workmode 0 --args preview-size1024x600,picture-size640x480, --time 10 adb forwardtcp:1234 tcp:1234 //设置adb的转发 ./prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin/arm-linux-androideabi-gdb out/tar…

近红外光谱脑功能成像(fNIRS):1.光学原理、变量选取与预处理

一、朗伯-比尔定律与修正的朗伯-比尔定律 朗伯-比尔定律 是一个描述光通过溶液时被吸收的规律。想象你有一杯有色液体&#xff0c;比如一杯红茶。当你用一束光照射这杯液体时&#xff0c;光的一部分会被液体吸收&#xff0c;导致透过液体的光变弱。朗伯-比尔定律告诉我们&#…

mmdetection3D指定版本安装指南

1. 下载指定版本号 选择指定版本号下载mmdetection3d的源码&#xff0c;如这里选择的是0.17.2版本 git clone https://github.com/open-mmlab/mmdetection3d.git -b v0.17.22. 安装 cd mmdetection3d安装依赖库 pip install -r requirment.txt编译安装 pip install -v e .…

redis主从复制哨兵模式集群管理

主从复制&#xff1a; 主从复制是高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份&#xff0c;以及对于读操作的负载均衡和简单的故障恢复。缺陷&#xff1a;故障恢复无法自动化&#xff1b;写操作无法负载均衡&…

软件测试与质量保证 | 云班课简答题库

目录 第14章 质量相关简答题 第15章 测试实际相关简答题 第16章 测试基本相关简答题 第14章 质量相关简答题 1. 简述基本的测量原则。 测量应该基于该应用领域正确的理论之上&#xff0c;并在测量的定义中确定测度的目标&#xff1b;每一个技术测量的定义应该具有一致性和客…

HbuilderX:安卓打包证书.keystore生成与使用

前置条件 已安装jdk或配置好jre环境。 .keystore生成 打开cmd,切换到目标路径,输入以下命令, keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore 输入密钥库口令(要记住), 然后输入一系列信息, …

ui.perfetto.dev sql 查询某个事件范围内,某个事件的耗时并降序排列

ui.perfetto.dev sql 查询某个事件范围内,某个事件的耗时并降序排列 1.打开https://ui.perfetto.dev 导入Chrome Trace Json文件2.ParallelMLP.forward下的RowParallelLinear.forward3.点击Query(SQL),在输入框中输入以下内容,按CtrlEnter,显示查询结果4.点击Show timeline,点击…

2024年07年01日 Redis数据类型以及使用场景

String Hash List Set Sorted Set String&#xff0c;用的最多&#xff0c;对象序列化成json然后存储 1.对象缓存&#xff0c;单值缓存 2.分布式锁 Hash&#xff0c;不怎么用到 1.可缓存经常需要修改值的对象&#xff0c;可单独对对象某个属性进行修改 HMSET user {userI…

Windows快速打开某个路径下的PowerShell

按住Shift右键打开&#xff1a; 在桌面或者文件夹页面中&#xff0c;按住右键&#xff0c;在弹出的右键菜单中选择“在终端中打开”或“在此处打开Powershell窗口“&#xff0c;就可打开windows PowerShell界面&#xff0c;且路径为桌面或打开的文件夹所在路径。

浅谈贝叶斯定理

引言 贝叶斯定理用于确定事件的条件概率。它以一位英国统计学家的名字命名&#xff0c;托马斯贝叶斯他在1763年发现了这个公式。贝叶斯定理是数学中一个非常重要的定理&#xff0c;它为一种独特的统计推断方法奠定了基础。贝氏推论它用于根据可能与事件相关的条件的先验知识&a…

C++基础(三):C++入门(二)

上一篇博客我们正式进入C的学习&#xff0c;这一篇博客我们继续学习C入门的基础内容&#xff0c;一定要学好入门阶段的内容&#xff0c;这是后续学习C的基础&#xff0c;方便我们后续更加容易的理解C。 目录 一、内联函数 1.0 产生的原因 1.1 概念 1.2 特性 1.3 面试题 …

用随机森林算法进行的一次故障预测

本案例将带大家使用一份开源的S.M.A.R.T.数据集和机器学习中的随机森林算法&#xff0c;来训练一个硬盘故障预测模型&#xff0c;并测试效果。 实验目标 掌握使用机器学习方法训练模型的基本流程&#xff1b;掌握使用pandas做数据分析的基本方法&#xff1b;掌握使用scikit-l…

三大常用集合

1.Set集合 在Java中&#xff0c;Set是一种集合类型&#xff0c;它是一种不允许包含重复元素的集合&#xff0c;每个元素在Set中是唯一的。Set接口的常用实现类有HashSet、TreeSet和LinkedHashSet。以下是关于Set集合的一些重要特点和用法&#xff1a; 特点&#xff1a; 不允…

什么是mysql的回表操作

MySQL中的“回表”操作是指在执行查询时&#xff0c;由于索引结构的限制&#xff0c;数据库系统需要从非聚集索引&#xff08;Secondary Index&#xff09;中找到主键值&#xff0c;然后使用这些主键值回溯到聚集索引&#xff08;Clustered Index&#xff09;中获取完整的行数据…

珠江电缆,承载您梦想的每一度电

在现代社会&#xff0c;电力无处不在&#xff0c;它不仅是经济发展的动力&#xff0c;更是每个人生活中不可或缺的能量来源。而在这个电力驱动的世界里&#xff0c;有一家企业默默地承载着千家万户的梦想&#xff0c;它就是珠江电缆。 连接梦想的每一度电 珠江电缆成立于2001…

使用Java实现单元测试:JUnit教程

使用Java实现单元测试&#xff1a;JUnit教程 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在软件开发中&#xff0c;单元测试是保证代码质量和功能正确性的重要手段之一。JUnit是Java语言中最流行…

绝区零国际服下载 一键下载绝区零国际服教程

绝区零是一款米哈游倾情打造的全新都市幻想动作角色扮演游戏。在游戏中&#xff0c;我们将扮演一名绳匠&#xff0c;这是为出于各种原因需要进入危险空洞的人提供指引的专业人士。您将与独特的角色一起踏上冒险之旅&#xff0c;携手探索空洞&#xff0c;对战强大敌人&#xff0…

【状态估计】线性高斯系统的状态估计——离散时间的递归滤波

前两篇文章介绍了离散时间的批量估计、离散时间的递归平滑&#xff0c;本文着重介绍离散时间的递归滤波。 前两篇位置&#xff1a;【状态估计】线性高斯系统的状态估计——离散时间的批量估计、【状态估计】线性高斯系统的状态估计——离散时间的递归平滑。 离散时间的递归滤波…

ollama将模型永远加载在显存里

问题解析 我们在使用ollma部署大语言模型的时候,如果部署的模型尺寸较大,往往在第一次加载的时候需要花费大量的时间加载模型;等加载完成后,如果长时间不调用模型,我们会发现模型已经被释放掉了,又要重新加载,导致体验感极差. 这是为什么呢?因为在没被调用时,ollama默认在显…