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

这篇具有很好参考价值的文章主要介绍了C# Winfrom实例:武汉智能安检闸机数据接收和解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

软件操作流程:

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

数据格式截图:

C# Winfrom实例:武汉智能安检闸机数据接收和解析,c#,网络,开发语言

安检闸机图片:

C# Winfrom实例:武汉智能安检闸机数据接收和解析,c#,网络,开发语言

知识点介绍: 
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));
        }
    }
}

运行结果:

C# Winfrom实例:武汉智能安检闸机数据接收和解析,c#,网络,开发语言文章来源地址https://www.toymoban.com/news/detail-825593.html

到了这里,关于C# Winfrom实例:武汉智能安检闸机数据接收和解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C# 给winfrom窗体添加皮肤控件

    如何快速给C# winform添加好看的皮肤C# Winform中窗体的美化 SkinEngine的应用 皮肤控件换肤素材包,IrisSkin2.dll皮肤素材资源下载  压缩包内一共有22种皮肤素材,使用说明:把控件拖到你的form上,只需一行代码,即可实现整个form包括其所有控件的皮肤的更换,  总共有几十套皮肤

    2024年02月05日
    浏览(49)
  • C#之Winfrom自定义输入框对话框。

    在你的程序中,在需要触发输入框的地方添加一个按钮或其他事件处理器。例如,你可以在按钮点击事件中执行相应的代码和逻辑。 通过以上步骤,你可以在 WinForms 程序中创建一个带有输入框的自定义窗体,并在点击确定按钮后获取用户输入的值。确保根据实际需求修改输

    2024年02月14日
    浏览(37)
  • WinFrom、C# 学习记录五 开发一个鼠标自动点击小软件

            经常会被问到需要点击软件的,主要都是玩游戏的盆友,但是也有其它用途的。所以简单弄了一个,打算每当有时间,有需求,就加一些小功能。         这里主要是要记录一下相关开发工作,也记录一些使用/更新的信息。         【2022/08/22】版本v1.0(初始版

    2024年02月16日
    浏览(51)
  • AI助力智能安检,基于图像目标检测实现危险品X光智能安全检测系统

    基于AI相关的技术来对一些重复性的但是又比较重要的工作来做智能化助力是一个非常有潜力的场景,关于这方面的项目开发实践在我之前的文章中也有不少的实践,感兴趣的话可以自行移步阅读即可: 《AI助力智能安检,基于目标检测模型实现X光安检图像智能检测分析》

    2024年02月11日
    浏览(35)
  • 循环可变化的集合 数组 datatable 等 || c# winfrom DataGridView 动态UI下载功能

          1,使用组件DataGridView 2,使用DataSource来控制表格展示的数据来源(注意:来源需要是DataTable类型) 3,需要用到异步线程。如果是不控制数据源的话,需要使用UI安全线程;(使用Control.Invoke或Control.BeginInvoke方法) 4,DataGridView的列如果设置图片,尽量代码设置 5,DataT

    2024年02月19日
    浏览(42)
  • ESP32网络开发实例-UDP数据发送与接收

    本文将详细介绍在Arduino开发环境中,如何实现ESP32通过UDP协议进行数据发送与接收。 用户数据报协议 (UDP) 是一种跨互联网使用的通信协议,用于对时间敏感的传输,例如视频播放或 DNS 查找。它通过在数据传输之前不正式建立连接来加速通信。这使得数据可以非常快速地传输

    2024年02月07日
    浏览(48)
  • c# winfrom DataGridView 动态UI下载功能(内含GIF图) || 循环可变化的集合 数组 datatable 等

      1,使用组件DataGridView 2,使用DataSource来控制表格展示的数据来源(注意:来源需要是DataTable类型) 3,需要用到异步线程。如果是不控制数据源的话,需要使用UI安全线程;(使用Control.Invoke或Control.BeginInvoke方法) 4,DataGridView的列如果设置图片,尽量代码设置 5,DataTable类型

    2024年02月20日
    浏览(35)
  • C#与松下PLC串口通讯发送,接收数据

    记录与学习 第一次跟PLC打交道,C#与松下plc交互读写功能,很多东西都是自己在网上找的,整理了下做个记录  引入“Panasonic.dll”文件 下载地址 百度盘百度网盘 请输入提取码  提取码:8vnm  public Panasonic.PLC Sp_PLC;   Sp_PLC.WCS(\\\"R\\\", \\\"1\\\", true);//提示PLC软件初始化完成,可以正常工

    2023年04月12日
    浏览(54)
  • C#串口通信从入门到精通(14)——多个串口接收数据

    我们在开发串口通信程序时,有时候会需要连接不止一个串口,这时候该怎么写程序呢?本文就来介绍多个串口数据的接收 我们在之前的专栏中介绍了串口数据的发送,当时有提到过,我们是通过创建一个SerialPort类的对象,然后利用这个对象来实现对串口的访问,那么以此

    2024年02月05日
    浏览(89)
  • C#串口通信从入门到精通(26)——多个串口多个线程发送数据和接收数据

    我们在开发串口程序的过程中有时候会遇到多个串口,并且多个串口也需要在多个线程进行操作,本文就来讲解如何实现多个串口在多线程下的安全发送与接收。 我们首先使用虚拟串口助手虚拟COM1、COM2这一对串口;COM3、COM4这一对串口,然后使用代码操作COM1,然后打开一个

    2024年02月11日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包