C# Winfrom实例:武汉智能安检闸机数据接收和解析

news2024/11/22 16:49:26

项目介绍:
本实例主要是接收安检闸机的数据解析并显示到界面上,只做功能实现,不做界面美化

硬件:闸机一个、网线一根、电脑主机
开发环境:vs2017 系统:win10
涵盖知识点:tcp通讯、文件写入、多线程,委托、类型转换等

软件操作流程:

点击开始监听按钮,8999要是未被占用则开启监听,然后人刷身份证通过安检闸机就可以接收到数据

数据格式截图:

39eb0464d46e37ec68a2d0a0b8da9f88.png

安检闸机图片:

ae6c88135023f70fbc5ba1b4e1a14cdb.png

知识点介绍: 
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.Any
                Socket 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;
            else
                item = "人证核验:失败" + "\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));
        }
    }
}

运行结果:

d9f3bde67aaf2323ea7f866a1e9d1b77.png

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

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

相关文章

通过Linux终端搭建基于HTTP隧道的文件传输系统

嘿&#xff0c;Linux小侠们&#xff0c;准备好挑战一项酷炫的任务了吗&#xff1f;今天我们要一起通过Linux终端搭建一个基于HTTP隧道的文件传输系统&#xff0c;让我们的文件在网络的海洋中畅游无阻&#xff01; 在开始之前&#xff0c;让我们先来想象一下这个场景&#xff1…

吃个桃桃~

解法&#xff1a;暴力、排序 #include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; #define endl \n struct tree {int index;int peach; }; bool cmp(tree a,tree b) {if (a.peach ! b.peach)return …

提升数据库操作技能:发现MyBatis-Plus学习网站的无限可能!

介绍&#xff1a;MyBatis-Plus是一个对MyBatis框架进行增强的工具&#xff0c;旨在简化开发流程并提升开发效率。以下是MyBatis-Plus的一些主要特点&#xff1a; CRUD操作简化&#xff1a;MyBatis-Plus提供了一些列的CRUD操作方法&#xff0c;这些方法已经封装好&#xff0c;可…

计算机服务器中了devos勒索病毒怎么办?Devos勒索病毒解密数据恢复

网络技术的不断发展与更新&#xff0c;为企业的生产运营提供了有利保障&#xff0c;企业的生产运营离不开数据支撑&#xff0c;通过企业数据可以综合调整发展运营方向&#xff0c;但网络是一把双刃剑&#xff0c;近期&#xff0c;云天数据恢复中心接到许多企业的求助&#xff0…

文件系统创建分区

目录 一、EXT4文件系统创建分区 1.使用 fdisk 分区 2.格式化写入文件系统 3.挂载 临时挂载 永久挂载 二、XFS文件系统创建分区 1.使用 gdisk 分区 2.格式化写入文件系统 3.挂载 临时挂载 永久挂载 三、创建swap分区 1.查看文件系统 2.新建swap分区 3.格式化分区 …

CSP-202006-2-稀疏向量

CSP-202006-2-稀疏向量 【60分思路-暴力枚举】 显然u[100000000], v[100000000]过不了7,8,9,10的样例&#xff0c;但是思路也比较简单易懂&#xff0c;初学者可以参考 #include <iostream> using namespace std; int u[100000000], v[100000000]; long long inner; in…

Java中的关键字

✨✨ 所属专栏&#xff1a; Java基石&#xff1a;深入探索Java核心基础✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; Java中的关键字是一些具有特殊含义的单词&#xff0c;它们在语法中有特定的用途&#xff0c;不能用作标识符&am…

ai写作工具哪具好,3款AI写作软件来揭晓

ai写作工具在当今信息爆炸的时代中正变得越来越受欢迎。随着人工智能技术的不断发展&#xff0c;越来越多的AI写作软件涌现出来&#xff0c;它们的功能和性能也日益完善。在这篇文章中&#xff0c;我们将揭晓3款备受推崇的AI写作软件&#xff0c;探讨它们各自的特点和优势。 第…

网络机顶盒哪个好?内行分享网络机顶盒排名

网络机顶盒是电视机的必备搭配&#xff0c;依然是不可缺少的部分&#xff0c;我作为网络机顶盒的从业者&#xff0c;经常给被问到的就是网络机顶盒哪个好&#xff0c;不同品牌之间差异较大&#xff0c;今天给大家分享业内最新发布的网络机顶盒排名&#xff0c;看看目前哪些网络…

前端简单知识复习

1.symbol类型 Symbol 是 ECMAScript 6 中引入的一种新的基本数据类型&#xff0c;它表示独一无二的值。Symbol 值是通过 Symbol() 函数创建的。 Symbol 值具有以下特点&#xff1a; 独一无二性&#xff08;唯一性&#xff09;&#xff1a;每个通过 Symbol() 函数创建的 Symb…

泛微e-office系统存在敏感信息泄露 附POC软件

免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 1. 泛微e-office系统简介 微信公众号搜索:南风漏洞复…

阿里云国际-在阿里云服务器上快速搭建幻兽帕鲁多人服务器

幻兽帕鲁是最近流行的新型生存游戏。该游戏一夜之间变得极为流行&#xff0c;同时在线玩家数量达到了200万。然而&#xff0c;幻兽帕鲁的服务器难以应对大量玩家的压力。为解决这一问题&#xff0c;幻兽帕鲁允许玩家建立专用服务器&#xff0c;其提供以下优势&#xff1a; &am…

Ubuntu22部署MySQL5.7详细教程

Ubuntu22部署MySQL5.7详细教程 一、下载MySQL安装包二、安装MySQL三、启动MySQL检查状态登录MySQL 四、开启远程访问功能1、允许其他主机通过root访问数据库2、修改配置文件&#xff0c;允许其他IP通过自定义端口访问 五、使用Navicat连接数据库 默认情况下&#xff0c;Ubuntu2…

Python urllib模块学习

HTTP协议 HTTP 协议&#xff1a;一般指HTTP(超文本传输)协议。 HTTP是为Web浏览器和Web服务器之间的通信而设计的&#xff0c;基于TCP/IP通信协议嘞传递数据。 HTTP消息结构 客户端请求消息 客户端发送一个HTTP请求到服务器的请求消息包括以下格式 请求行(request line)请求…

python毕设选题 - 大数据二手房数据爬取与分析可视化 -python 数据分析 可视化

# 1 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通…

什么是HTTP代理,socks5代理?它们的区别是什么?

什么是HTTP代理&#xff1f; HTTP代理是一种常见的网络代理方式&#xff0c;它通过在客户端和服务器之间建立一个中间层&#xff0c;将客户端的请求转发给服务器&#xff0c;并将服务器的响应返回给客户端。HTTP代理通常用于访问受限制的网站&#xff0c;或者在网络中隐藏客户…

以太网通讯工业RFID读写器|传感器RH623A安装方法与注意事项

以太网通讯工业RFID读写器|传感器RH623A是一款支持MODBUS-TCP工业以太网&#xff0c;MODBUS-RTU(RS232)工业总线型高频读写设备&#xff0c;支持ISO15693协议&#xff0c;最高支持3米/秒的相对速度下准确读卡不漏读&#xff0c;满足根类工业环境下应用&#xff0c;广泛应用于AG…

WebGL中开发科学数据可视化应用

WebGL在科学数据可视化领域有广泛的应用&#xff0c;可以用于呈现和解释复杂的科学数据。以下是在WebGL中开发科学数据可视化应用时的一些建议&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.选择合…

多目图像拼接算法

图像拼接一般要经过图像特征提取、特征匹配、融合等步骤来实现。 特征匹配与变换: SIFT(尺度不变特征变换)SURF(加速鲁棒特征)ORB(Oriented FAST and Rotated BRIEF)AKAZE(加速的KAZE特征)全景图像拼接算法: 基于特征匹配的拼接:利用特征点匹配找到重叠区域,然后进…

C++之Easyx——图形库的基本功能(2):来点色彩

一、setbkcolor 函数定义 void EGEAPI setbkcolor(color_t color, PIMAGE pimg NULL); // 设置当前绘图背景色&#xff08;设置并做背景色像素替换&#xff09; 使用说明 void EGEAPI setbkcolor(颜色RGB, PIMAGE pimg NULL); // 设置当前绘图背景色&#xff08;…