C# TCP Server服务端多线程监听RFID读卡器客户端上传的读卡数据

本示例使用设备介绍:液显WIFI无线网络HTTP协议RFID云读卡器可编程实时可控开关TTS语-淘宝网 (taobao.com) 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace WindowsFormsApplication1
{
    public partial class Form13 : Form
    {
        public Form13()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        Thread listenThread = null; //负责监听客户端的线程
        Socket listenSocket = null; //负责监听客户端的套接字                                   
        Socket interactSocket = null;//创建一个负责和客户端通信的套接字 

        Dictionary<string, Socket> dicSockets = new Dictionary<string, Socket>(); //套接字集合
        Dictionary<string, Thread> dicThreads = new Dictionary<string, Thread>();  //线程集合
        List<string> list_SealedClients = new List<string>();//被屏蔽用户的名单

        private void Form13_Load(object sender, EventArgs e)
        {
            GetIp();
        }

        private void GetIp()
        {
            Form1 f1;
            f1 = (Form1)this.Owner;
            f1.Refresh();

            for (int i = 0; i < f1.comboBox4.Items.Count; i++)
            {
                comboBox4.Items.Add(f1.comboBox4.Items[i]);
            }
            if (comboBox4.Items.Count > 0)
            {
                comboBox4.SelectedIndex = 0;
                btn_conn.PerformClick();
            }
        }

        private void btn_conn_Click(object sender, EventArgs e)
        {            
            try
            {
                if (btn_conn.Text == "开启服务器")
                {
                    //(IPv4协议,双向,TCP协议)
                    listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                    //网络结点endpoint需要IP和端口号
                    //port是 与 address 关联的端口号,或为 0 以指定任何可用端口。port 以主机顺序排列。
                    //IPEndPoint m_Endpoint = new IPEndPoint(IPAddress.Parse(txb_ip.Text.Trim()), int.Parse(txb_port.Text.Trim()));
                    string ipadd = comboBox4.Text.Trim();
                    IPEndPoint m_Endpoint = new IPEndPoint(IPAddress.Parse(ipadd), int.Parse(txb_port.Text.Trim()));

                    //绑定网络结点
                    listenSocket.Bind(m_Endpoint);

                    //将监听Socket置于侦听状态,(backlog):挂起连接队列的最大长度。
                    listenSocket.Listen(10);

                    //创建一个线程执行的委托,无返回值
                    ThreadStart threadFun = new ThreadStart(ListenConnectingRequest);

                    //创建一个监听线程 
                    listenThread = new Thread(threadFun);

                    //线程设置为后台运行
                    listenThread.IsBackground = true;

                    //启动线程
                    listenThread.Start();

                    AddLog("开始监听客户端传来的信息!");
                    btn_conn.Text = "关闭服务器";
                }
                else
                {
                    //关闭监听
                    listenSocket.Close();//关闭监听套接字,并释放
                    listenThread.Abort();//强行中断
                    AddLog("结束监听客户端传来的信息!");
                    AddLog("关闭服务器,断开所有客户端用户的连接!");

                    //切断所有客户端的连接
                    for (int i = 0; i < listBox1.Items.Count; i++)
                    {
                        string str = listBox1.Items[i].ToString();
                        Socket m_socket = dicSockets[str];
                        m_socket.Close();
                    }
                    btn_conn.Text = "开启服务器";
                }
            }
            catch (Exception f)
            {
                MessageBox.Show("错误:" + f.ToString(), "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                AddLog("服务端启动服务失败!");
            }
        }

        public void AddLog(string str)
        {
            if (listBox2.Items.Count > 50)
            {
                listBox2.Items.Clear();
            }
            listBox2.Items.Add(str);
            listBox2.SelectedIndex = listBox2.Items.Count - 1;
        }


        /// <summary>
        /// 监听客户端发来的请求
        /// </summary>
        private void ListenConnectingRequest()
        {
            while (true)  //持续不断监听客户端发来的请求
            {
                try
                {
                    interactSocket = listenSocket.Accept();//阻塞,直到接收到客户端连接请求

                    // 向列表控件中添加客户端的IP信息;
                    listBox1.Items.Add(interactSocket.RemoteEndPoint.ToString());

                    // 将与客户端连接的套接字对象添加到集合中;
                    dicSockets.Add(interactSocket.RemoteEndPoint.ToString(), interactSocket);
                    AddLog(DateTime.Now.ToString("hh:mm:ss.fff") + " 客户端" + interactSocket.RemoteEndPoint.ToString() + "连接服务器成功! "); //客户端IP

                    //创建一个通信线程 
                    Thread threadRecvMsg = new Thread(new ParameterizedThreadStart(ServerRecvMsg));
                    threadRecvMsg.IsBackground = true;
                    //启动线程
                    threadRecvMsg.Start(interactSocket);
                    dicThreads.Add(interactSocket.RemoteEndPoint.ToString(), threadRecvMsg); // 将新建的线程 添加 到线程的集合中去。
                }
                catch (Exception)
                {
                }
            }
        }

        private void ServerRecvMsg(object m_InteractSocket)
        {
            Socket serverSocket = (Socket)m_InteractSocket; //类型转换 objec->Socket
            string str = interactSocket.RemoteEndPoint.ToString();
            while (true)
            {
                //创建一个内存缓冲区 其大小为1024*1024字节  即1M
                byte[] arrServerRecMsg = new byte[1024 * 1024];
                try
                {
                    //将接收到的信息存入到内存缓冲区,并返回其字节数组的长度
                    int length = serverSocket.Receive(arrServerRecMsg);
                    //如果屏蔽名单中有这个用户,屏蔽信息接收
                    if (!list_SealedClients.Contains(str))
                    {
                        //将机器接受到的字节数组转换为人可以读懂的字符串
                        string strSRecMsg = "";        //   Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
                        for (int i = 0; i < length; i++)
                        {
                            strSRecMsg = strSRecMsg + arrServerRecMsg[i].ToString("X2") + " ";
                        }
                        if (strSRecMsg.Length != 0)
                        {
                            //显示接收的信息
                            string dispstr = DateTime.Now.ToString("hh:mm:ss.fff") + " FromIP " + interactSocket.RemoteEndPoint.ToString() + " :" + strSRecMsg;
                            AddLog(dispstr);
                            //this.BeginInvoke(new Update1(EditUi1), dispstr, arrServerRecMsg, length);        //显示接收到的数据包,并根据情况回应设备
                            AnalyticGetData(arrServerRecMsg, length, str);
                        }
                    }

                }
                catch (Exception)
                {
                    AddLog(DateTime.Now.ToString("hh:mm:ss.fff") + " 客户端" + str + "已断开服务器!");
                    // 从通信套接字 集合中删除被中断连接的通信套接字;
                    dicSockets.Remove(str);
                    // 从通信线程集合中删除被中断连接的通信线程对象;
                    dicThreads.Remove(str);
                    // 从列表中移除被中断的连接IP
                    listBox1.Items.Remove(str);
                    // 从屏蔽列表从清除
                    list_SealedClients.Remove(str);
                    break;//结束该线程
                }
            }
        }

        private void ServerSingSenddata(byte[] senddata)
        {
            string strKey = "";
            try
            {
                strKey = listBox1.Text.Trim();
                if (string.IsNullOrEmpty(strKey))   // 判断是不是选择了发送的对象;
                {
                    MessageBox.Show("请选择你要发送的在线客户端!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    if (!list_SealedClients.Contains(strKey))
                    {
                        string sendmsg = "";
                        for (int i = 0; i < senddata.Length; i++)
                        {
                            sendmsg = sendmsg + senddata[i].ToString("X2") + " ";
                        }
                        dicSockets[strKey].Send(senddata);                                                         //显示发送的信息
                        AddLog(DateTime.Now.ToString("hh:mm:ss.fff") + " SendTo " + strKey + " :" + sendmsg);
                        AddLog("");
                    }
                    else
                    {
                        MessageBox.Show(strKey + "已经被屏蔽!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("错误:" + ex.ToString(), "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                AddLog(dicSockets[strKey].RemoteEndPoint.ToString() + "客户端已断开连接,无法发送信息!");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            listBox2.Items.Clear(); 
        }

        private void button3_Click(object sender, EventArgs e)
        {
            string copystr;
            copystr = "";
            for (int i = 0; i <= listBox2.Items.Count - 1; i++)
            {
                copystr = copystr + (string)listBox2.Items[i] + "\r\n";
            }
            Clipboard.Clear();
            Clipboard.SetDataObject(copystr);

            MessageBox.Show("显示的数据报文已拷贝到剪切板", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            AddLog("接收线程数量:" + dicThreads.Count.ToString());
        }

        private void button5_Click(object sender, EventArgs e)
        {
            //1.没有选择退出
            if (listBox1.SelectedIndex == -1)
            {
                MessageBox.Show("请选择要断开的客户端!","警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            //2.切断客户端的连接       
            string RemoteEndPointStr = listBox1.SelectedItem.ToString();
            AddLog("强制断开客户端" + RemoteEndPointStr + "的连接!");
            listBox1.SelectedIndex = -1;
            Socket disconnSocket = dicSockets[RemoteEndPointStr];
            disconnSocket.Close();
        }

        //解析接收到的数据信息,并回应驱动读卡器显示文字、蜂鸣响声、播报语音、开关继电器等
        private void AnalyticGetData(byte[] getdata, int length, string IPort)
        {
            string msginf = "";
            uint cardhao;
            string cardnumberstr = "";
            switch (getdata[0])
            {
                case 0xc1:  //接收到IC读卡器读取的卡号
                case 0xcf:  //接收到IC离开读卡器
                    if (getdata[0] == 0xc1)
                    {
                        msginf = "数据解析:IC读卡器刷卡数据";
                    }
                    else { msginf = "数据解析:IC卡离开读卡器"; }
                    msginf = msginf + ",IP[" + getdata[1].ToString() + "." + getdata[2].ToString() + "." + getdata[3].ToString() + "." + getdata[4].ToString();
                    msginf = msginf + ",机号[" + Convert.ToString(getdata[5] + getdata[6] * 256) + "],数据包序号[" + Convert.ToString(getdata[7] + getdata[8] * 256) + "],卡号长度[" + Convert.ToString(getdata[9]) + "],16进制卡号[";
                    for (int i = 10; i < 10 + getdata[9]; i++)
                    {
                        msginf = msginf + getdata[i].ToString("X2");
                    }
                    cardhao = (uint)(getdata[13] * 256 * 256 * 256 + getdata[12] * 256 * 256 + getdata[11] * 256 + getdata[10]);
                    cardnumberstr = "0000000000" + Convert.ToString(cardhao);//卡号
                    cardnumberstr = cardnumberstr.Substring(cardnumberstr.Length - 10, 10);
                    msginf = msginf + "],转10进制卡号[" + cardnumberstr;

                    msginf = msginf +  "],唯一设备序号[";
                    for (int i = 10 + getdata[9]; i < length; i++)
                    {
                        msginf = msginf + getdata[i].ToString("X2");
                    }
                    msginf = msginf + "]";
                    AddLog(msginf);
                    AddLog("");
                    Response(IPort);
                    break;

                case 0xd1: //接收到ID读卡器读取的卡号
                case 0xdf: //接收到ID卡离开读卡器
                    if (getdata[0] == 0xd1)
                    {
                        msginf = "数据解析:ID读卡器刷卡数据";
                    }
                    else { msginf = "数据解析:ID卡离开读卡器"; }
                    msginf = msginf + ",IP[" + getdata[1].ToString() + "." + getdata[2].ToString() + "." + getdata[3].ToString() + "." + getdata[4].ToString();
                    msginf = msginf + ",机号[" + Convert.ToString(getdata[5] + getdata[6] * 256) + "],数据包序号[" + Convert.ToString(getdata[7] + getdata[8] * 256) + "]";

                    cardhao = (uint)(getdata[12] * 256 * 256 * 256 + getdata[11] * 256 * 256 + getdata[10] * 256 + getdata[9]);
                    cardnumberstr = "0000000000" + Convert.ToString(cardhao);//卡号
                    cardnumberstr = cardnumberstr.Substring(cardnumberstr.Length - 10, 10);

                    msginf = msginf + ",16进制卡号[" + getdata[9].ToString("X2") + getdata[10].ToString("X2") + getdata[11].ToString("X2") + getdata[12].ToString("X2") + getdata[13].ToString("X2") + "],转10进制卡号[" + cardnumberstr + "]";

                    msginf = msginf + ",唯一设备序号[";
                    for (int i = 14; i < length; i++)
                    {
                        msginf = msginf + getdata[i].ToString("X2");
                    }
                    msginf = msginf + "]";
                    AddLog(msginf);
                    AddLog("");
                    Response(IPort);
                    break;

                case 0xf3: //接收到读卡器心跳包
                    msginf = "数据解析:读卡器读卡器心跳包,IP[" + getdata[1].ToString() + "." + getdata[2].ToString() + "." + getdata[3].ToString() + "." + getdata[4].ToString();
                    msginf = msginf + ",机号[" + Convert.ToString(getdata[5] + getdata[6] * 256) + "],数据包序号[" + Convert.ToString(getdata[7] + getdata[8] * 256) + "],心跳包类型[" + Convert.ToString(getdata[9]) + "]";
                    msginf = msginf + ",长度[" + Convert.ToString(getdata[10]) + "]";
                    msginf = msginf + ",继电器状态[" + getdata[11].ToString("X2") + "]";
                    msginf = msginf + ",外部输入状态[" + getdata[12].ToString("X2") + "]";
                    msginf = msginf + ",随机动态码[" + getdata[13].ToString("X2") + getdata[14].ToString("X2") + getdata[15].ToString("X2") + getdata[16].ToString("X2") + "]";
                    for (int i = 17; i < length; i++)
                    {
                        msginf = msginf + getdata[i].ToString("X2");
                    }
                    msginf = msginf + "]";
                    AddLog(msginf);
                    AddLog("");
                    break;
            }
        }

        //回应读卡器驱动显示文字、蜂鸣响声、播报语音等
        private void Response(string IPort)
        {
            byte[] databuf = new byte[280];
            int i;
            int dispbytes;    //显示文字节数
            int speakbytes;   //语音播报字节表
            int sendbytes;    //报文数据长度           

            dispbytes = 34;   //双行屏34,四行屏72显示长度,如不显示文字可以为0

            string strls = "[v";
            if (SYDX.Value <= 16)
            {
                strls = strls + (SYDX.Value.ToString()).Trim() + "]";  //设置语音大小,在需要发送的语音字符串中任何位置加入[v10],表示将音量调到10级(范围0~16,0表示静音,16最大,每次重开机后,音量重置为10级)!
            }
            else { strls = strls + "16]"; }

            strls = strls + textBox12.Text.Trim();

            byte[] SpeakArr = System.Text.Encoding.GetEncoding(936).GetBytes(strls);//TTS语音转换为Ansi
            speakbytes = SpeakArr.GetLength(0);             //语音长度
            sendbytes = 11 + dispbytes + speakbytes + 4;    //总计发送数据长度

            databuf[0] = 0x5C;      //表示驱动蜂鸣器+TTS组合语音+显示文字+继电器
            databuf[1] = 0;         //机号低位,
            databuf[2] = 0;         //机号高位,如果高低位都为0表示任意机号,TCP是点对点通讯

            if (checkBox2.Checked)   //可以同时发出声响
            {
                databuf[3] = (byte)(comboBox3.SelectedIndex);
                if (radioButton2.Checked)  //背光灯不变
                {
                    databuf[3] = (byte)(databuf[3] | 0x80);
                }
            }
            else
            {
                databuf[3] = 0xff;//不发出声响
                if (radioButton2.Checked)  //背光灯不变
                {
                    databuf[3] = (byte)(databuf[3] & 0x80);
                }
            }

            switch (comboBox2.SelectedIndex)  //继电器
            {
                case 1:
                    databuf[4] = 0xF1;
                    break;
                case 2:
                    databuf[4] = 0xF2;
                    break;
                case 3:
                    databuf[4] = 0xF3;
                    break;
                case 4:
                    databuf[4] = 0xF4;
                    break;
                case 5:
                    databuf[4] = 0xF5;
                    break;
                case 6:
                    databuf[4] = 0xF6;
                    break;
                case 7:
                    databuf[4] = 0xF7;
                    break;
                case 8:
                    databuf[4] = 0xF8;
                    break;
                default:
                    databuf[4] = 0xF0;
                    break;
            }
            i = Convert.ToInt32(textBox11.Text);      //继电器时长
            databuf[5] = (byte)(i % 256);
            databuf[6] = (byte)(i / 256);

            databuf[7] = (byte)(numericUpDown1.Value);//显示保留时间,单位为秒,为255时表示永久显示
            databuf[8] = 0;                           //在显示屏中的哪个位置开始
            databuf[9] = (byte)dispbytes;             //显示字符串长度 0-34为全屏

            databuf[10] = (byte)speakbytes;           //TTS语音长度

            strls = textBox12.Text + "                                            ";
            byte[] strlsansi = System.Text.Encoding.GetEncoding(936).GetBytes(strls);//显示文字转换为Ansi
            for (i = 0; i < speakbytes; i++)
            {
                databuf[11 + i] = (Byte)strlsansi[i];
            }

            for (i = 0; i < speakbytes; i++)          //连播语音代码
            {
                databuf[11 + databuf[9] + i] = (Byte)SpeakArr[i];
            }

            databuf[10 + databuf[9] + speakbytes + 1] = 0x55;   //防干扰后缀
            databuf[10 + databuf[9] + speakbytes + 2] = 0xAA;
            databuf[10 + databuf[9] + speakbytes + 3] = 0x66;
            databuf[10 + databuf[9] + speakbytes + 4] = 0x99;

            int sendlen = 10 + databuf[9] + speakbytes + 5;
            byte[] sendbuf = new byte[sendlen];
            string dispstr = DateTime.Now.ToString("hh:mm:ss.fff") + " SendTo " + IPort + " :";
            for (i = 0; i < sendlen; i++)          //连播语音代码
            {
                sendbuf[i] = databuf[i];
                dispstr = dispstr + databuf[i].ToString("X2") + " ";
            }

            dicSockets[IPort].Send(sendbuf);
            AddLog(dispstr);
            AddLog(" ");
        }

        private void button6_Click(object sender, EventArgs e)
        {
            byte[] sendbuf = new byte[4];
            sendbuf[0] = 0x96;      //声响指令
            sendbuf[1] = 0;         //机号低位,
            sendbuf[2] = 0;         //机号高位,如果高低位都为0表示任意机号,TCP是点对点通讯
            sendbuf[3] = (byte)(comboBox3.SelectedIndex);

            ServerSingSenddata(sendbuf);
        }

        private void button7_Click(object sender, EventArgs e)
        {
            byte[] sendbuf = new byte[6];
            sendbuf[0] = 0x78;      //继电器指令
            sendbuf[1] = 0;         //机号低位,
            sendbuf[2] = 0;         //机号高位,如果高低位都为0表示任意机号,TCP是点对点通讯

            switch (comboBox2.SelectedIndex)
            {
                case 1:
                    sendbuf[3] = 0xF1;
                    break;
                case 2:
                    sendbuf[3] = 0xF2;
                    break;
                case 3:
                    sendbuf[3] = 0xF3;
                    break;
                case 4:
                    sendbuf[3] = 0xF4;
                    break;
                case 5:
                    sendbuf[3] = 0xF5;
                    break;
                case 6:
                    sendbuf[3] = 0xF6;
                    break;
                case 7:
                    sendbuf[3] = 0xF7;
                    break;
                case 8:
                    sendbuf[3] = 0xF8;
                    break;
                default:
                    sendbuf[3] = 0xF0;
                    break;
            }
            int i = Convert.ToInt32(textBox11.Text);//延时
            sendbuf[4] = (byte)(i % 256);
            sendbuf[5] = (byte)(i / 256);

            ServerSingSenddata(sendbuf);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            byte[] sendbuf = new byte[6];
            sendbuf[0] = 0x78;      //继电器指令
            sendbuf[1] = 0;         //机号低位,
            sendbuf[2] = 0;         //机号高位,如果高低位都为0表示任意机号,TCP是点对点通讯

            switch (comboBox2.SelectedIndex)
            {
                case 1:
                    sendbuf[3] = 0xE1;
                    break;
                case 2:
                    sendbuf[3] = 0xE2;
                    break;
                case 3:
                    sendbuf[3] = 0xE3;
                    break;
                case 4:
                    sendbuf[3] = 0xE4;
                    break;
                case 5:
                    sendbuf[3] = 0xE5;
                    break;
                case 6:
                    sendbuf[3] = 0xE6;
                    break;
                case 7:
                    sendbuf[3] = 0xE7;
                    break;
                case 8:
                    sendbuf[3] = 0xE8;
                    break;
                default:
                    sendbuf[3] = 0xE0;
                    break;
            }
            int i = Convert.ToInt32(textBox11.Text);//延时
            sendbuf[4] = (byte)(i % 256);
            sendbuf[5] = (byte)(i / 256);

            ServerSingSenddata(sendbuf);
        }

        private void button10_Click(object sender, EventArgs e)
        {
            string strls;
            byte[] sendbuf = new byte[39];
            int i;

            sendbuf[0] = 0x5a;      //显示文字的指令
            sendbuf[1] = 0;         //机号低位,
            sendbuf[2] = 0;         //机号高位,如果高低位都为0表示任意机号,TCP是点对点通讯

            if (checkBox2.Checked)   //可以同时发出声响
            {
                sendbuf[3] = (byte)(comboBox3.SelectedIndex);
                if (radioButton2.Checked)  //背光灯不变
                {
                    sendbuf[3] = (byte)(sendbuf[3] | 0x80);
                }
            }
            else
            {
                sendbuf[3] = 0xff;//不发出声响
                if (radioButton2.Checked)  //背光灯不变
                {
                    sendbuf[3] = (byte)(sendbuf[3] & 0x80);
                }
            }

            sendbuf[4] = (byte)(numericUpDown1.Value);//显示保留时间,单位为秒,为255时表示永久显示

            strls = textBox12.Text + "                                        ";
            byte[] strlsansi = System.Text.Encoding.GetEncoding(936).GetBytes(strls);//转换为Ansi //显示文字的ASCII码

            for (i = 0; i < 34; i++)
            {
                sendbuf[5 + i] = (Byte)strlsansi[i];
            }
            ServerSingSenddata(sendbuf);   
        }

        private void button9_Click(object sender, EventArgs e)
        {
            byte[] databuf = new byte[280];
            int i;
            int dispbytes;    //显示文字节数
            int speakbytes;   //语音播报字节表
            int sendbytes;    //报文数据长度           

            dispbytes = 34;   //双行屏34,四行屏72显示长度,如不显示文字可以为0

            string strls = "[v";
            if (SYDX.Value <= 16)
            {
                strls = strls + (SYDX.Value.ToString()).Trim() + "]";  //设置语音大小,在需要发送的语音字符串中任何位置加入[v10],表示将音量调到10级(范围0~16,0表示静音,16最大,每次重开机后,音量重置为10级)!
            }
            else { strls = strls + "16]"; }

            strls = strls + textBox12.Text.Trim();

            byte[] SpeakArr = System.Text.Encoding.GetEncoding(936).GetBytes(strls);//TTS语音转换为Ansi
            speakbytes = SpeakArr.GetLength(0);             //语音长度
            sendbytes = 11 + dispbytes + speakbytes + 4;    //总计发送数据长度

            databuf[0] = 0x5C;      //表示驱动蜂鸣器+TTS组合语音+显示文字+继电器
            databuf[1] = 0;         //机号低位,
            databuf[2] = 0;         //机号高位,如果高低位都为0表示任意机号,TCP是点对点通讯

            if (checkBox2.Checked)   //可以同时发出声响
            {
                databuf[3] = (byte)(comboBox3.SelectedIndex);
                if (radioButton2.Checked)  //背光灯不变
                {
                    databuf[3] = (byte)(databuf[3] | 0x80);
                }
            }
            else
            {
                databuf[3] = 0xff;//不发出声响
                if (radioButton2.Checked)  //背光灯不变
                {
                    databuf[3] = (byte)(databuf[3] & 0x80);
                }
            }

            switch (comboBox2.SelectedIndex)  //继电器
            {
                case 1:
                    databuf[4] = 0xF1;
                    break;
                case 2:
                    databuf[4] = 0xF2;
                    break;
                case 3:
                    databuf[4] = 0xF3;
                    break;
                case 4:
                    databuf[4] = 0xF4;
                    break;
                case 5:
                    databuf[4] = 0xF5;
                    break;
                case 6:
                    databuf[4] = 0xF6;
                    break;
                case 7:
                    databuf[4] = 0xF7;
                    break;
                case 8:
                    databuf[4] = 0xF8;
                    break;
                default:
                    databuf[4] = 0xF0;
                    break;
            }
            i = Convert.ToInt32(textBox11.Text);      //继电器时长
            databuf[5] = (byte)(i % 256);
            databuf[6] = (byte)(i / 256);

            databuf[7] = (byte)(numericUpDown1.Value);//显示保留时间,单位为秒,为255时表示永久显示
            databuf[8] = 0;                           //在显示屏中的哪个位置开始
            databuf[9] = (byte)dispbytes;             //显示字符串长度 0-34为全屏

            databuf[10] = (byte)speakbytes;           //TTS语音长度

            strls = textBox12.Text + "                                            ";
            byte[] strlsansi = System.Text.Encoding.GetEncoding(936).GetBytes(strls);//显示文字转换为Ansi
            for (i = 0; i < speakbytes; i++)
            {
                databuf[11 + i] = (Byte)strlsansi[i];
            }

            for (i = 0; i < speakbytes; i++)          //连播语音代码
            {
                databuf[11 + databuf[9] + i] = (Byte)SpeakArr[i];
            }

            databuf[10 + databuf[9] + speakbytes + 1] = 0x55;   //防干扰后缀
            databuf[10 + databuf[9] + speakbytes + 2] = 0xAA;
            databuf[10 + databuf[9] + speakbytes + 3] = 0x66;
            databuf[10 + databuf[9] + speakbytes + 4] = 0x99;

            int sendlen = 10 + databuf[9] + speakbytes + 5;
            byte[] sendbuf = new byte[sendlen];
            for (i = 0; i < sendlen; i++)          //连播语音代码
            {
                sendbuf[i] = databuf[i];
            }
            ServerSingSenddata(sendbuf);   
        }

        private void comboBox4_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {                
                    listenSocket.Close();//关闭监听套接字,并释放
                    listenThread.Abort();//强行中断
                    AddLog("结束监听客户端传来的信息!");
                    AddLog("关闭服务器,断开所有客户端用户的连接!");

                    //切断所有客户端的连接
                    for (int i = 0; i < listBox1.Items.Count; i++)
                    {
                        string str = listBox1.Items[i].ToString();
                        Socket m_socket = dicSockets[str];
                        m_socket.Close();
                    }
                    btn_conn.Text = "开启服务器";    
            }
            catch (Exception f)
            {
                btn_conn.Text = "开启服务器";
            }
        }

        private void Form13_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                listenSocket.Close();//关闭监听套接字,并释放
                listenThread.Abort();//强行中断
                AddLog("结束监听客户端传来的信息!");
                AddLog("关闭服务器,断开所有客户端用户的连接!");

                //切断所有客户端的连接
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    string str = listBox1.Items[i].ToString();
                    Socket m_socket = dicSockets[str];
                    m_socket.Close();
                }
                btn_conn.Text = "开启服务器";
            }
            catch (Exception f)
            {
                btn_conn.Text = "开启服务器";
            }
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mindspore mindcv图像分类算法;模型保存与加载

参考&#xff1a; https://www.mindspore.cn/tutorials/en/r1.3/save_load_model.html https://github.com/mindspore-lab/mindcv/blob/main/docs/zh/tutorials/finetune.md 1、mindspore mindcv图像分类算法 import os from mindcv.utils.download import DownLoad import o…

移远EC600U-CN开发板 day03

控件探索-按钮&#xff08;lv.btn&#xff09; (1) 创建并显示一个按钮 * 核心代码 btn lv.btn(scr) #将按钮与src对象关联 btn.align(lv.ALIGN.CENTER,0,0) #居中显示&#xff08;第1个0表示x的偏移量&#xff0c;第2个0表示相对于y的偏移量&#xff09; label lv.l…

小白学爬虫:手机app分享商品短连接获取淘宝商品链接接口|淘宝淘口令接口|淘宝真实商品链接接口|淘宝商品详情接口

通过手机APP分享的商品短链接&#xff0c;我们可以调用相应的接口来获取淘口令真实URL&#xff0c;进而获取到PC端的商品链接及商品ID。具体步骤如下&#xff1a; 1、通过手机APP分享至PC端的短链接&#xff0c;调用“item_password”接口。 2、该接口将返回淘口令真实URL。 3…

从使用的角度看 ByConity 和 ClickHouse 的差异

自 ClickHouse Inc 宣布其重要新功能仅在 ClickHouse Cloud 上开放以来&#xff0c;一些关注 ByConity 开源的社区小伙伴也来询问 ByConity 后续开源规划。为回答社区疑问&#xff0c;我们将之前分享的关于 ByConity 与 ClickHouse 相关功能对比的 webinar 整理为文章&#xff…

Git 基础知识回顾及 SVN 转 Git 自测

背景 项目开发过程中使用的版本控制工具是 SVN&#xff0c;Git 多有耳闻&#xff0c;以前也偶尔玩过几次&#xff0c;但是工作中不用&#xff0c;虽然本地也有环境&#xff0c;总是不熟练。 最近看一本网络开源技术书时&#xff0c;下载源码部署了一下&#xff0c;又温故了一…

助力工业数字化!TDengine 与恩菲 MIM+ 工业互联网平台实现兼容性互认

在云计算、物联网、5G等新兴技术快速发展的当下&#xff0c;制造企业想要运用新兴技术实现数字化转型&#xff0c;工业互联网平台的应用和打造是非常关键的转型要素。在工业互联网平台的发展中&#xff0c;数据处理上存在的问题一直都是令企业所头疼的&#xff0c;越来越多的案…

Java并发编程第11讲——AQS设计思想及核心源码分析

Java并发包&#xff08;JUC&#xff09;中提供了很多并发工具&#xff0c;比如前面介绍过的ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore、FutureTask等锁或者同步部件&#xff0c;它们的实现都用到了一个共同的基类——AbstractQueuedSynchronizer&…

汽车网络安全渗透测试概述

目录 1.汽车网络安全法规概述 1.1 国外标准 1.2 国内标准 2.汽车网络安全威胁分析 2.1 汽车网络安全资产定义 2.2 汽车网络安全影响场景及评级示例 3.汽车网络安全渗透测试描述 3.1 参考法规 3.2 渗透测试内容 4.小结 1.汽车网络安全法规概述 近年来&#xff0c;汽车…

【UE4】UE编辑器乱码问题

环境&#xff1a;UE4.27、vs2019 如何解决 问题原因&#xff0c;UE的编码默认是UTF-8&#xff0c;VS的默认编码是GBK 通过"高级保存选项" 直接修改VS的 .h头文件 的 编码 为 UTF-8 步骤1. 步骤2. 修改编码后&#xff0c;从新编译&#xff0c;然后就可以解决编辑器…

很多个pdf怎么合并在一起?

很多个pdf怎么合并在一起&#xff1f;作为一个办公室的伙伴&#xff0c;对于PDF格式肯定不会陌生。它强大的功能为我们的工作提供了许多便利。由于PDF文件格式的稳定性和安全性较高&#xff0c;我们通常在工作或学习中使用它来传输文件&#xff0c;很多人都喜欢将办公文件都做成…

Java用log4j写日志

日志可以方便追踪和调试问题&#xff0c;以前用log4net写日志&#xff0c;换Java了改用log4j写日志&#xff0c;用法和log4net差不多。 到apache包下载下载log4j的包&#xff0c;解压后把下图两个jar包引入工程 先到网站根下加一个log4j2.xml的配置文件来配置日志的格式和参…

自动驾驶行业观察之2023上海车展-----车企发展趋势(3)

合资\外资发展 宝马&#xff1a;i7、iX1新车亮相&#xff0c;未来将持续发力电动化、数字化&#xff08;座舱&#xff09; 宝马在本次车展重点展示了电动化产品&#xff0c;新发车型为i7 M70L、iX1、及i vision Dee概念车等车型。 • 展示重点&#xff1a;电动化数字化&#…

STM32H750之FreeRTOS学习--------(五)临界段代码保护

FreeRTOS 文章目录 FreeRTOS五、临界段代码保护临界段代码保护函数任务级进入临界段任务级退出临界段中断级进入临界段中断级退出临界段 任务调度器的挂起和恢复挂起任务调度器恢复任务调度器挂起任务调度器恢复任务调度器 五、临界段代码保护 临界段代码也叫做临界区&#xf…

Android EditText 实现强制性弹出只能输入英文的键盘

如果 EditText 控件不做任何特殊处理&#xff0c;例如笔者手机默认弹出的是百度输入法的软键盘&#xff0c;可实现中英文切换&#xff0c;并且自带英文单词智能联想功能&#xff08;与系统安装输入法和设置相关&#xff09;。但在某些应用场景下&#xff0c;例如在英语APP里练习…

RabbitMQ(高级特性):限流

消费端限流 在rabbitmq中&#xff0c;使用消费端限流必须开启手动签收信息 过MQ可以对请求进行“削峰填谷”&#xff0c;即通过消费端限流的方式限制消息的拉取速度&#xff0c;达到保护消费端的目的。 生产者批量发送消息&#xff1a; Test public void testSendBatch() {…

DBever 连接trino时区问题 The datetime zone id ‘GMT+08:00‘ is not recognised

DBever连接trino 测试连接成功&#xff0c;但是执行sql报时区不对、如果你默认使用的是大于jdk8的版本 会存在这个问题&#xff0c;因为jdk版本 jdk8 和jdk17 版本默认时区是不同的 trino官网明确说明了时区默认跟jdk走 解决方案 可以先行查看JDK本地时区库版本&#xff0c;执…

Django初窥门径-自定义用户模型

前言 自定义用户模型在Django应用中是一个重要的话题&#xff0c;它涉及到如何根据您的项目需求以及特定的用户身份验证和授权需求来调整用户模型。在以下前言中&#xff0c;我将讲述为什么自定义用户模型是如此重要以及其潜在的优势&#xff1a; 随着Web应用的不断发展&…

工业路由器网关的网络协议之NAT技术

在物联网通讯领域&#xff0c;NAT技术能将内网的一个私有IP转换成一个公网IP去接入互联网&#xff0c;解决组建局域网络时私有IP地址无法在公网上进行路由的问题。 NAT&#xff08;Network Address Translation&#xff09;的三种方式&#xff1a; 静态NAT 1、一个私有IP对应…

在微信小程序中怎么实现刮刮卡抽奖活动

在当今的数字化时代&#xff0c;微信小程序已经成为一种广泛使用的营销工具。通过各种互动活动&#xff0c;企业可以吸引用户的关注&#xff0c;提升品牌影响力。其中&#xff0c;刮刮卡抽奖活动是一种特别受欢迎的形式。本文将为你详细介绍如何在微信小程序中实现刮刮卡抽奖活…

Python中通过socketserver库创建服务端

socketserver库是Python的标准库&#xff0c;提供了套接字服务端的框架&#xff0c;通过该框架可以简化服务端的创建流程。 1 socketserver库的导入 通过如图1显示的代码导入socketserver库。 图1 导入socketserver库 2 通过socketserver库创建TCP服务端 通过socketserver库…