生活随笔
收集整理的這篇文章主要介紹了
C sharp实例:华盾武器门数据接收和解析
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
項(xiàng)目介紹:
本實(shí)例主要是接收安檢金屬門的數(shù)據(jù)解析并顯示到界面上,只做功能實(shí)現(xiàn),不做界面美化
硬件:金屬門一個(gè)、網(wǎng)線一根、電腦主機(jī),金屬門網(wǎng)線可以直接接到電腦主機(jī)上
開(kāi)發(fā)環(huán)境:vs2017 系統(tǒng):win10
涵蓋知識(shí)點(diǎn):tcp通訊、文件寫(xiě)入、多線程,委托、類型轉(zhuǎn)換等
軟件操作流程:
點(diǎn)擊開(kāi)始監(jiān)聽(tīng)按鈕,9082要是未被占用則開(kāi)啟監(jiān)聽(tīng),然后人通過(guò)金屬門就可以接收到數(shù)據(jù)
金屬門數(shù)據(jù)協(xié)議截圖:
知識(shí)點(diǎn)介紹:? 1. socket.Listen(10); 官方給出的解釋:掛起連接隊(duì)列的最大長(zhǎng)度。?連接隊(duì)列,即連接池,也就是要保證掛起的連接池中至少要有10個(gè)連接??????????????? 我解釋一下,為什么要提前準(zhǔn)備10個(gè)掛起的連接,原因就是每當(dāng)一個(gè)新用戶接入進(jìn)來(lái)時(shí),就需要立即創(chuàng)建一個(gè)socket,創(chuàng)建也需要時(shí)間和消耗系統(tǒng)資源,這樣就會(huì)影響高并發(fā)的性能??????????????? ,用不用,先放那,用的時(shí)候直接取即
2.?Socket clientSocket = socket.Accept();
AcceptSocket是同步的,你可以用異步通訊的BeginAcceptSocket或者用多線程。沒(méi)有請(qǐng)求到達(dá),就會(huì)“卡”住,術(shù)語(yǔ)叫程序阻塞,socket同步通訊就是這個(gè)步驟,執(zhí)行到AcceptSocket就會(huì)阻塞等待請(qǐng)求,直到有請(qǐng)求到達(dá)時(shí),才執(zhí)行后面的語(yǔ)句,并且處理這個(gè)請(qǐng)求
3.?while (true) 因?yàn)榻M要一直監(jiān)聽(tīng),所以得死循環(huán);
4. 開(kāi)啟一個(gè)后來(lái)線程,不然主界面會(huì)假死
new Thread(delegate () {主體代碼;}) { IsBackground = true }.Start();
5.從其它線程訪問(wèn)主線程控件需要委托,不然界面不會(huì)有數(shù)據(jù)的 this.Invoke((EventHandler)delegate??????????????????????? {??????????????????????????? richTextBox1.Text += “”;
??????????????????????? }); 不完善的地方:金屬門每通過(guò)一次會(huì)發(fā)送三條數(shù)據(jù),三條數(shù)據(jù)間有時(shí)間間隔,所以為了接收到完整數(shù)據(jù)我?Thread.Sleep(1000);睡了1秒鐘,所以幾個(gè)人同時(shí)通過(guò)金屬門會(huì)有數(shù)據(jù)丟包,暫時(shí)沒(méi)做相應(yīng)處理。
完整代碼如下:
using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Windows.Forms;
using System.IO;
using System.Threading;namespace TcpRecive
{public partial class mainForm : Form{public mainForm(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){textBox1.Text = "9082"; }public void tcpRecive(int port){if (PortIsUse(port)){label1.Text = "端口" + port.ToString() + "被占用"; return;}else label1.Text = "端口" + port.ToString() + "沒(méi)有占用,監(jiān)聽(tīng)已開(kāi)啟";new Thread(delegate (){int recv;//定義接收數(shù)據(jù)長(zhǎng)度變量IPAddress ip = IPAddress.Parse("192.168.1.119");//接收端所在IP 192.168.1.119換成127.0.0.1不可以為什么?IPEndPoint ipEnd = new IPEndPoint(ip, port);//接收端所監(jiān)聽(tīng)的接口,ip也可以用IPAddress.AnySocket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化一個(gè)Socket對(duì)象socket.Bind(ipEnd);//綁定套接字到一個(gè)IP地址和一個(gè)端口上(bind());//官方給出的解釋:掛起連接隊(duì)列的最大長(zhǎng)度。//連接隊(duì)列,即連接池,也就是要保證掛起的連接池中至少要有10個(gè)連接//我解釋一下,為什么要提前準(zhǔn)備10個(gè)掛起的連接,原因就是每當(dāng)一個(gè)新用戶接入進(jìn)來(lái)時(shí),就需要立即創(chuàng)建一個(gè)socket,創(chuàng)建也需要時(shí)間和消耗系統(tǒng)資源,這樣就會(huì)影響高并發(fā)的性能//,用不用,先放那,用的時(shí)候直接取即可socket.Listen(10);while (true){try{byte[] data = new byte[1024];//對(duì)data清零//for (int i = 0; i < data.Length; i++) { data[i] = 0; }Socket clientSocket = socket.Accept(); //一旦接受連接,創(chuàng)建一個(gè)客戶端Thread.Sleep(1000);//不延時(shí)收不到完整數(shù)據(jù),可能是三組數(shù)據(jù)間有時(shí)間間隔recv = clientSocket.Receive(data);// 或者clientSocket.Receive(data, data.Length, SocketFlags.None);獲取收到的數(shù)據(jù)的長(zhǎng)度if (recv == 0) //如果收到的數(shù)據(jù)長(zhǎng)度小于0,則退出break;//string stringData = Encoding.UTF8.GetString(data);//string stringData = byteToHexStr(data);//MessageBox.Show( dataDecode(data).ToString());//dataDecode(data);string stringData = "0x"+BitConverter.ToString(data, recv-32,32).Replace("-", " 0x").ToLower();//只取最后32個(gè)字節(jié)的數(shù)據(jù)//string stringData = Encoding.ASCII.GetString(data);this.Invoke((EventHandler)delegate{richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss") + " 安檢人數(shù):" + dataDecode(data, 0, recv)+ " 報(bào)警人數(shù):" + dataDecode(data, 1, recv) + " 報(bào)警信息:" + alarmPosition(data, recv)+ "\n" + stringData + "\n";});fileWrite(DateTime.Now.ToString("yy-MM-dd hh:mm:ss") + "\n" + stringData);}catch { };}}){ IsBackground = true }.Start();}/// <summary>/// 字節(jié)數(shù)組轉(zhuǎn)16進(jìn)制字符串/// </summary>/// <param name="bytes"></param>/// <returns></returns>public static string byteToHexStr(byte[] bytes){string returnStr = "";if (bytes != null){for (int i = 0; i < bytes.Length; i++){returnStr += bytes[i].ToString("X2");}}return returnStr;}public int dataDecode(byte[] data, int type,int dataLength){int personNum = 0;switch (type){case 0:personNum = Convert.ToInt32(BitConverter.ToString(data, dataLength-27, 4).Replace("-", ""), 16); break; //取出對(duì)應(yīng)位置連續(xù)四個(gè)字節(jié)并轉(zhuǎn)換為通過(guò)人數(shù)case 1:personNum = Convert.ToInt32(BitConverter.ToString(data, dataLength-23, 4).Replace("-", ""), 16); break; //取出對(duì)應(yīng)位置連續(xù)四個(gè)字節(jié)并轉(zhuǎn)換為報(bào)警人數(shù) default:; break;}return personNum;}public string alarmPosition(byte[] bytes, int dataLength){string alarmStr = "";for(int i=0;i<10;i++){if (bytes[dataLength + i - 19] == 0x00)continue;//0x00則退出本次循環(huán)switch (bytes[dataLength+i-19]){case 0x01: alarmStr = "區(qū)位" + (i + 1).ToString() +"工具刀槍"; break;case 0x02: alarmStr = "區(qū)位" + (i + 1).ToString() + "馬口鐵罐體"; break;case 0x03: alarmStr = "區(qū)位" + (i + 1).ToString() + "鋁制易拉罐"; break;case 0x04: alarmStr = "區(qū)位" + (i + 1).ToString() + "違禁品混合"; break;case 0x05: alarmStr = "區(qū)位" + (i + 1).ToString() + "銅制鋁制管體"; break;case 0x09: alarmStr = "區(qū)位" + (i + 1).ToString() + "手機(jī)手表"; break;case 0x0a: alarmStr = "區(qū)位" + (i + 1).ToString() + "全金屬報(bào)警"; break;case 0X30: alarmStr = "區(qū)位" + (i + 1).ToString() + "非磁性槍支"; break;default: alarmStr = ""; break;}}if (alarmStr == "")return "無(wú)報(bào)警";else return alarmStr;}public void fileWrite(string str){if (!File.Exists("info.txt"))File.Create("info.txt").Close();//創(chuàng)建文件并關(guān)閉StreamWriter sw = new StreamWriter("info.txt",true);//向文件追加數(shù)據(jù)sw.WriteLine(str);sw.Close();}//通過(guò) IPGlobalProperties來(lái)獲取本機(jī)的網(wǎng)絡(luò)連接的信息,并通過(guò)GetActiveTcpListeners找到已用端口,進(jìn)而可以知道所需的端口是否已被占用public static bool PortIsUse(int port){bool isUse = false;IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();//找到已用端口foreach (IPEndPoint endPoint in ipEndPoints){if (endPoint.Port == port)//判斷是否存在{isUse= true;break;}}return isUse;}private void button1_Click(object sender, EventArgs e){tcpRecive(int.Parse(textBox1.Text));}}
}
運(yùn)行結(jié)果:
以上代碼完全純手工打造,如果有疑問(wèn)歡迎留言,喜歡的小伙伴們可以多多分享,讓更多志同道合的伙伴們加入我們的微信交流群一起學(xué)習(xí)、進(jìn)步!
總結(jié)
以上是生活随笔為你收集整理的C sharp实例:华盾武器门数据接收和解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。