網口串口(Serialport)服務器

文章所用工具
http://t.csdnimg.cn/2gIR8icon-default.png?t=N7T8http://t.csdnimg.cn/2gIR8

搭建服務器界面

操作配置文件保存方式類

public string FileName {  get; set; }public IniHelper(string name) {this.FileName = name; //在構造函數中給路徑賦值}
1 先導入c語言進行讀取操作ini文件的方法

GetPrivateProfileString() 獲取ini配置文件的數據
? ? ? ? //static 靜態的變量 只能聲明在當前文件中,不能在其他源文件進行使用。
? ? ? ? //extern 用來聲明外部的符號 可以跨文件使用。

[DllImport("Kernel32.dll")] //導入方法所在dll文件
public static extern Int32 GetPrivateProfileString(string sectionName, //段名 string keyName,//鍵名string defaultName,//當鍵不存在默認值。StringBuilder returnValue,// 讀取到數據uint size,// 讀取數據的大小string fileName// ini文件路徑);
2添加寫入ini文件的c方法
[DllImport("Kernel32.dll")]
public static extern Int32 WritePrivateProfileString(string sectionName, //段名 string keyName,//鍵名string value,//設置的值string fileName// ini文件路徑);

不直接使用上面的倆個c語言的方法 再封裝到其他方法進行使用
? ? ? ? //讀取ini數據的方法
? ? ? ? //ReadData("Second","B","Setting.ini") "10"
? ? ? ? //參數1 段名 ,參數2鍵名 ,參數3是文件路徑

public static string ReadData(string sectionName,string keyName,string fileName)
{StringBuilder sb = new StringBuilder(512); //512是存儲的大小GetPrivateProfileString(sectionName, keyName, string.Empty, sb, 512, fileName);return sb.ToString();
}

對上面ReadData再封裝,封裝能直接返回指定類型的數據的方法
? ? ? ? //傳進段名和鍵名獲取內容
? ? ? ? //以后Read("段名","鍵名") ?返回字符串類型

public string Read(string sectionName,string keyName)
{return ReadData(sectionName, keyName,this.FileName);}

如果讀取數據 沒讀取到 給賦一個初值
? ? ? ? Read("Secotion",A,"1000") ?最終結果:hello world
? ? ? ? Read("Secotion",C,"1000") ?最終結果:1000

 public string Read(string sectionName, string keyName,string defaultValue){string v = Read(sectionName, keyName);if (string.IsNullOrEmpty(v)){return defaultValue;}return v;}

讀取的時候 返回一個整型的數據值

Read("Secotion",C,1000) ?最終結果:1000
Read("Secotion",A,1000) ?最終結果:1000

?

public int Read(string s1, string k1, int d1)
{string v = Read(s1, k1);if (int.TryParse(v,out int value)){return value;}else{return d1;}}
public bool Read(string s1, string k1, bool d1)
{string v = Read(s1, k1);if (bool.TryParse(v,out bool value)){return value;}else{//不能轉成boolif (v=="1"||v=="OK"||v=="ON"||v=="YES"){return true;}else if(v=="0"||v=="NO"||v=="OFF"||v.ToUpper()=="OFF"){//如果值以上幾種請求 值為falsereturn false;}else{return d1;}}
}
//ini值是double類型
public double Read(string s1, string k1, double d1)
{string v = Read(s1, k1);if (double.TryParse(v, out double value)){return value;}else{return d1;}}

封裝寫入數據的方法
先定義一個靜態寫入方法

public static  int WriteData(string s1,string k1,string v,string file)
{return WritePrivateProfileString(s1,k1,v,file);
}

封裝方法

//在封裝Write方法傳遞 傳進段名 鍵名 值是字符串
public int Write(string s1,string k1,string v1)
{return WriteData(s1, k1, v1, this.FileName);
}//在封裝Write方法傳遞 傳進段名 鍵名 值是整型
public int Write(string s1, string k1, int v1)
{return WriteData(s1, k1, v1.ToString(), this.FileName);
}//在封裝Write方法傳遞 傳進段名 鍵名 值是bool
public int Write(string s1, string k1, bool v1)
{return WriteData(s1, k1, v1?"1":"0", this.FileName);
}//在封裝Write方法傳遞 傳進段名 鍵名 值是時間格式
public int Write(string s1, string k1, DateTime v1)
{return WriteData(s1, k1, v1.ToString("yyyy-MM-dd HH-mm:ss"), this.FileName);
}

using調用?

編輯配置文件

存入File文件夾中,放到Dubug文件夾中

服務器

 IniHelper Ini;string[] botelvs = new string[] { "1200", "4800", "9600", "13200" };
1 讀取配置文件
string dirPath = Path.Combine(Application.StartupPath, "File"); // debug/File
string filePath = Path.Combine(dirPath, "Setting.ini");// debug / file/setting.ini
Ini = 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_DataReceivd;// 3 處理界面顯示默認值 也就是從ini文件讀取數據
readStting();// 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 (Exception ex){MessageBox.Show("TCP啟動失敗");// 把tcp關閉等操作foreach(var item  in lists){item.Close(); // 關閉所有的客戶端}listen.Stop();panel2.BackColor = Color.Gray;}
}
接收數據
void tcpReceive(TcpClient c1)
{new Task(() =>{NetworkStream stream = c1.GetStream();try{MessageBox.Show("111");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;}// 把數據轉給串口 發送數據,com8能接收到消息,serialPort1.Write(bs, 0, length);}}catch{c1.Close();lists.Remove(c1);}}).Start();
}
亮燈
async void tcpLiangDeng()
{this.Invoke((Action)(() =>{textBox2.Text = (int.Parse(textBox2.Text) + 1).ToString();// 亮燈panel4.BackColor = Color.Pink;}));// 過一段時間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 枚舉值this.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;}}private void readStting()
{// 先配置串口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;}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{radioButton1.Checked = true;}textBox4.Text = Ini.Read("NetWork", "heartTime", "60000"); // 心跳間隔textBox5.Text = Ini.Read("NetWork", "heartTime", ""); // 心跳間隔checkBox1.Checked = Ini.Read("NetWork", "heartTime", false); // 心跳間隔}
接收串口傳遞的數據
private void SerialPort1_DataReceivd(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 接收到一條窗口數據 需要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.Pink;}));// 過一段時間await Task.Delay(70);this.Invoke((Action)(() =>{textBox1.Text = (int.Parse(textBox1.Text) + 1).ToString();// 關燈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)
{if(radioButton1.Checked){// 選中心跳timer1.Interval = string.IsNullOrEmpty(textBox4.Text) ? 6000 :  int.Parse(textBox4.Text);timer1.Tick += Timer1_Tick;timer1.Start();}
}

定時發送數據
private void Timer1_Tick(object sender, EventArgs e)
{// 定時發送數據string data = textBox5.Text; // 心跳數據 選中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);}
}
關閉心跳
rivate 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 8Ini.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);}

接受和發送默認值

效果如下

QQ202473-20354

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/40289.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/40289.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/40289.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python基于you-get下載網頁上的視頻

? 1.python 下載地址 下載 : https://www.python.org/downloads/ 2. 配置環境變量 配置 python_home 地址 配置 python_scripts 地址 在path 中加入對應配置 3. 驗證 ? C:\Users>python --version Python 3.12.4C:\Users>wheel version wheel 0.43.04. 下載 c…

Android SurfaceFlinger——本地窗口連接EGL API(二十四)

通過前面的文章我們屬性了 Surface 和 EGLSurface 的相關內容,這里我們繼續分析讓兩者相關聯的函數 native_window_api_connect()。 一、連接EGL API 1、window.h native_window_api_connect 源碼位置:/frameworks/native/libs/nativewindow/include/system/window.h st…

2024華為OD機試真題-分月餅-(C++/Python)-C卷D卷-200分

2024華為OD機試題庫-(C卷+D卷)-(JAVA、Python、C++) 題目描述 中秋節,公司分月餅,m 個員工,買了 n 個月餅,m ≤ n,每個員工至少分 1 個月餅,但可以分多個,單人分到最多月餅的個數是 Max1 ,單人分到第二多月餅個數是 Max2 ,Max1 - Max2 ≤ 3 ,單人分到第 n - 1…

Python從入門到放棄——浮點型變量

浮點型變量 前言 上一篇文章我們研究了整數類型變量&#xff0c;本次我們來開始研究一下浮點類型變量。 浮點類型 浮點數在計算機編程中扮演著重要的角色。它們是一種特殊的數據類型&#xff0c;用于存儲和處理小數或實數。在Python中&#xff0c;浮點數是由小數點分隔的…

如何在PhpStorm中運行SQL文件?

如何在PhpStorm中運行SQL文件&#xff1f; 提問&#xff1a;如何在PhpStorm中運行SQL文件&#xff1f; 解答&#xff1a;本文將詳細介紹如何在PhpStorm中運行SQL文件的步驟&#xff0c;包括如何配置數據庫連接和執行SQL腳本&#xff0c;并附帶示例SQL代碼。 1. 配置數據庫連…

迎接創新浪潮!RFID國軍標助力數字化裝備場轉型

隨著大數據、物聯網的飛速發展&#xff0c;數字化轉型已成為軍事發展的核心戰略之一。在這一重大歷史進程中&#xff0c;廣州一芯未來的RFID國軍標呈現出獨特而重要的作用。它不僅提升了裝備管理的效率和準確性&#xff0c;還增強了裝備的安全保障和資源配置的合理性。它以高效…

標題:哈爾濱等保測評:技術、管理和人員的協同作戰

在大數據時代&#xff0c;信息安全成為各行業不可忽視的關鍵議題。哈爾濱作為東北地區重要的經濟和科技中心&#xff0c;其等保測評工作更是成為了網絡安全領域的焦點。等保測評&#xff0c;即信息安全等級保護測評&#xff0c;不僅檢驗著技術的先進性&#xff0c;也考驗著管理…

Linux 下實現 MySQL 數據庫每天自動備份定時備份

創建一個備份腳本文件&#xff0c;例如 backup_mysql.sh&#xff0c;并將以下內容添加到該文件中&#xff1a; #!/bin/bash# 設置數據庫連接信息 DB_USER"your_database_user" DB_PASSWORD"your_database_password" DB_NAME"your_database_name"…

SpringMVC基礎詳解

文章目錄 一、SpringMVC簡介1、什么是MVC2、MVC架構模式與三層模型的區別3、什么是SpringMVC 二、HelloWorld程序1、pom文件2、springmvc.xml3、配置web.xml文件4、html文件5、執行Controller 三、RequestMapping注解1、value屬性1.1、基礎使用1.2、Ant風格&#xff08;模糊匹配…

在CenteOs7上安裝mysql8.0(Super詳細版)

在CenteOs7上安裝mysql8.0 為什么用Mysql8.0&#xff1f;如何下載下載地址需要提前準備下載步驟 服務器上安裝如何上傳到服務器&#xff1f;通過wget下載到服務器并解壓 開始安裝非必須安裝如果全部安裝執行順序 安裝完后&#xff0c;啟動mysql使用“systemctl”檢測mysqld服務…

python中unittest框架和pytest框架區別

unittest框架和pytest框架對比 類型unittest框架pytest框架安裝標準庫&#xff0c;無需額外安裝第三方單元測試庫&#xff0c;需要安裝用例編寫測試類必須要繼承 unittest.TestCase測試類命名以"Test"開頭&#xff0c;無需繼承&#xff0c;用例可以是函數&#xff0…

充分利用智慧校園人事系統,提升黨政職務管理

智慧校園人事系統中的黨政職務管理功能&#xff0c;是專為高校及教育機構設計的&#xff0c;旨在高效、精確地處理與黨政職務相關的各類事務&#xff0c;包括職務任命、任期管理、職責分配、考核評估等&#xff0c;以信息化手段促進黨務及行政工作的透明化、規范化。 該模塊首先…

根據服務器流量使用情況推算出網站流量的方法

根據服務器流量使用情況推算網站流量是一個涉及數據監測、分析和計算的過程。以下是一些基本步驟和方法&#xff1a; 1. 收集數據 首先&#xff0c;你需要獲取服務器的流量數據&#xff0c;這些數據通常包括&#xff1a; - 總流量&#xff1a;一定時間周期內服務器發送和接收的…

Jest是什么軟件?

Jest是一個由Facebook開發的開源JavaScript測試框架&#xff0c;它專為JavaScript項目的測試而設計&#xff0c;特別適用于React和Node.js環境。Jest以其簡單的配置、高效的性能和易用性而聞名&#xff0c;成為現代JavaScript項目中不可或缺的測試工具。以下是關于Jest的詳細解…

《Windows API每日一練》8.1 button控件二

8.1.4 按鈕 在BTNLOOK中顯示的前兩個按鈕是“按鍵”按鈕&#xff08;push button&#xff09;。此類按鈕是一種帶有 文本的矩形&#xff0c;這些文本是在CreateWindow調用的窗口文本參數中提供的。而CreateWindow 或MoveWindow調用中指定的寬度和高度則確定了矩形的大小。文本…

Spring-09

在 Spring 中如何注入一個 java 集合 在Spring中注入一個Java集合可以使用Autowired注解來實現。你可以在一個類的字段、構造函數或者setter方法上使用Autowired注解來注入一個集合。 下面是一個示例代碼&#xff0c;展示了如何在Spring中注入一個Java集合。 創建一個接口和實…

kotlin 中 string array 怎么表示

在 Kotlin 中&#xff0c;字符串數組可以使用 Array<String> 類型表示。你可以通過多種方式來創建和初始化字符串數組。以下是幾種常見的方法&#xff1a; 使用 arrayOf 函數&#xff1a; val stringArray arrayOf("Hello", "World", "Kotli…

面對全球新能源汽車合作發展創維汽車如何實現共贏

由全球新能源汽車合作組織(籌)主辦、中國電動汽車百人會承辦的首屆全球新能源汽車合作發展論壇(GNEV2024)于6月27日&#xff0c;6月28日在新加坡金沙會議展覽中心召開。創維汽車國際營銷公司總經理齊奎源受邀參會并作出分享。 本屆大會以推動全球新能源汽車產業協同發展與合作…

C語言課設--讀取文件并統計數據

讀取文件并統計數據 // 統計記事本英文字符數 //功能 &#xff1a; 讀 文件 a.txt 統計出各種 數字 大寫字母 小寫字母 0~9 A~Z a ~z各有多少個 程序主體框架如下&#xff1a; #include<stdio.h> int a[128]{0};//其中數組元素a[i]保存 ASCII 碼為i的字符的數量 v…