Csharp实例:武汉智能安检闸机数据接收和解析
項目介紹:
本實例主要是接收安檢閘機的數據解析并顯示到界面上,只做功能實現,不做界面美化
硬件:閘機一個、網線一根、電腦主機
開發環境:vs2017 系統:win10
涵蓋知識點:tcp通訊、文件寫入、多線程,委托、類型轉換等
軟件操作流程:
點擊開始監聽按鈕,8999要是未被占用則開啟監聽,然后人刷身份證通過安檢閘機就可以接收到數據
數據格式截圖:
安檢閘機圖片:
知識點介紹:?
1. socket.Listen(10); 官方給出的解釋:掛起連接隊列的最大長度。?連接隊列,即連接池,也就是要保證掛起的連接池中至少要有10個連接??????????????? 我解釋一下,為什么要提前準備10個掛起的連接,原因就是每當一個新用戶接入進來時,就需要立即創建一個socket,創建也需要時間和消耗系統資源,這樣就會影響高并發的性能??????????????? ,用不用,先放那,用的時候直接取即
2.?Socket clientSocket = socket.Accept();
AcceptSocket是同步的,你可以用異步通訊的BeginAcceptSocket或者用多線程。沒有請求到達,就會“卡”住,術語叫程序阻塞,socket同步通訊就是這個步驟,執行到AcceptSocket就會阻塞等待請求,直到有請求到達時,才執行后面的語句,并且處理這個請求
3.?while (true) 因為組要一直監聽,所以得死循環;
4. 開啟一個后來線程,不然主界面會假死 new Thread(delegate ()??????????? {主體代碼;})??????????? { IsBackground = true }.Start();
5.從其它線程訪問主線程控件需要委托,不然界面不會有數據的 this.Invoke((EventHandler)delegate??????????????????????? {??????????????????????????? richTextBox1.Text += “”;??????????????????????? });
完整代碼如下:
using System; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Windows.Forms; using System.IO; using System.Threading; using System.Text; using System.Drawing;namespace TcpRecive {public partial class mainForm : Form{public mainForm(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){textBox1.Text = "8999"; }public void tcpRecive(int port){if (PortIsUse(port)){label1.Text = "端口" + port.ToString() + "被占用"; return;}else label1.Text = "端口" + port.ToString() + "沒有占用,監聽已開啟";new Thread(delegate (){int recv;//定義接收數據長度變量//IPAddress ip = IPAddress.Parse("192.168.1.119");//接收端所在IP 192.168.1.119換成127.0.0.1不可以為什么?IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, port);//接收端所監聽的接口,ip也可以用IPAddress.AnySocket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化一個Socket對象socket.Bind(ipEnd);//綁定套接字到一個IP地址和一個端口上(bind());//官方給出的解釋:掛起連接隊列的最大長度。//連接隊列,即連接池,也就是要保證掛起的連接池中至少要有10個連接//我解釋一下,為什么要提前準備10個掛起的連接,原因就是每當一個新用戶接入進來時,就需要立即創建一個socket,創建也需要時間和消耗系統資源,這樣就會影響高并發的性能//,用不用,先放那,用的時候直接取即可socket.Listen(10);while (true){try{byte[] data = new byte[70000];//對data清零Socket clientSocket = socket.Accept(); //一旦接受連接,創建一個客戶端recv = clientSocket.Receive(data);// 或者clientSocket.Receive(data, data.Length, SocketFlags.None);獲取收到的數據的長度if (recv == 0) //如果收到的數據長度小于0,則退出break;//string stringData = Encoding.ASCII.GetString(data);string stringData = Encoding.UTF8.GetString(data);dataDecode(data);fileWrite(DateTime.Now.ToString("yy-MM-dd hh:mm:ss") + "\n" + stringData);}catch(Exception ex){MessageBox.Show(ex.ToString());}}}){ IsBackground = true }.Start();}/// <summary>/// 字節數組轉16進制字符串/// </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 void dataDecode(byte[] data){int dataL = 0, isPass = 0, nameL = 0, ethnicL = 0, sexL = 0, birthdayL = 0, adressL = 0, cardNoL = 0, startTimeL = 0, endTimeL = 0, cardImageL = 0, captureImageL = 0;string item = "", name = "", ethnic = "", sex = "", birthday = "", adress = "", cardNo = "", startTime = "", endTime = "";dataL = BitConverter.ToInt32(data, 0);//數據包大小,低字節在前面,高字節在后面isPass = BitConverter.ToInt32(data, 4);//人證核驗結果nameL = BitConverter.ToInt32(data, 8);//姓名長度name = Encoding.UTF8.GetString(data, 12, nameL);//姓名ethnicL = BitConverter.ToInt32(data, 12 + nameL);//民族長度ethnic = Encoding.UTF8.GetString(data, 16 + nameL, ethnicL);//民族sexL = BitConverter.ToInt32(data, 16 + nameL + ethnicL);//性別長度sex = Encoding.UTF8.GetString(data, 20 + nameL+ ethnicL,sexL);//性別birthdayL = BitConverter.ToInt32(data, 20 + nameL + ethnicL + sexL);birthday = Encoding.UTF8.GetString(data, 24 + nameL + ethnicL+sexL,birthdayL);//出生日期adressL = BitConverter.ToInt32(data, 24 + nameL + ethnicL + sexL + birthdayL);adress = Encoding.UTF8.GetString(data, 28 + nameL + ethnicL + sexL+birthdayL, adressL);//地址cardNoL = BitConverter.ToInt32(data, 28 + nameL + ethnicL + sexL + birthdayL + adressL);cardNo = Encoding.UTF8.GetString(data, 32 + nameL + ethnicL + sexL + birthdayL+adressL, cardNoL);//身份證號碼startTimeL = BitConverter.ToInt32(data, 32 + nameL + ethnicL + sexL + birthdayL + adressL + cardNoL);startTime = Encoding.UTF8.GetString(data, 36 + nameL + ethnicL + sexL + birthdayL + adressL+ cardNoL, startTimeL);//身份證起始時間endTimeL = BitConverter.ToInt32(data, 36 + nameL + ethnicL + sexL + birthdayL + adressL + cardNoL + startTimeL);endTime = Encoding.UTF8.GetString(data, 40 + nameL + ethnicL + sexL + birthdayL + adressL + cardNoL+ startTimeL, endTimeL);//身份證終止時間if (isPass == 1)item = "人證核驗:成功" + "\n姓名:" + name + "\n民族:" + ethnic + "\n性別:" + sex + "\n出生日期:" + birthday +"\n地址:" + adress + "\n身份證號碼:" + cardNo + "\n身份證起始時間:" + startTime + "\n身份證終止時間:" + endTime;elseitem = "人證核驗:失敗" + "\n姓名:" + name + "\n民族:" + ethnic + "\n性別:" + sex + "\n出生日期:" + birthday +"\n地址:" + adress + "\n身份證號碼:" + cardNo + "\n身份證起始時間:" + startTime + "\n身份證終止時間:" + endTime;cardImageL = BitConverter.ToInt32(data, 40 + nameL + ethnicL + sexL + birthdayL + adressL + cardNoL + startTimeL + endTimeL);MemoryStream ms1 = new MemoryStream(data, 44 + nameL + ethnicL + sexL + birthdayL + adressL + cardNoL + startTimeL + endTimeL, cardImageL);captureImageL = BitConverter.ToInt32(data, 44 + nameL + ethnicL + sexL + birthdayL + adressL + cardNoL + startTimeL + endTimeL + cardImageL);MemoryStream ms2 = new MemoryStream(data, 48 + nameL + ethnicL + sexL + birthdayL + adressL + cardNoL + startTimeL + endTimeL+cardImageL, captureImageL);//ms.Write(data, 44 + nameL + ethnicL + sexL + birthdayL + adressL + cardNoL + startTimeL + endTimeL, cardImageL);Image img1 = Image.FromStream(ms1);Image img2 = Image.FromStream(ms2);this.Invoke((EventHandler)delegate{richTextBox1.Text = item;pictureBox1.Image = img1; //更新在窗體控件上 pictureBox2.Image = img2;});ms1.Flush(); ms2.Flush();ms1.Close(); ms2.Close();ms1.Dispose(); ms2.Dispose();}public void fileWrite(string str){if (!File.Exists("info.txt"))File.Create("info.txt").Close();//創建文件并關閉StreamWriter sw = new StreamWriter("info.txt",true);//向文件追加數據sw.WriteLine(str);sw.Close();}//通過 IPGlobalProperties來獲取本機的網絡連接的信息,并通過GetActiveTcpListeners找到已用端口,進而可以知道所需的端口是否已被占用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));}} }運行結果:
總結
以上是生活随笔為你收集整理的Csharp实例:武汉智能安检闸机数据接收和解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这么简单的bug,你改了2天?
- 下一篇: AgileConfig轻量级配置中心1.