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->Socketstring str = interactSocket.RemoteEndPoint.ToString();while (true){//创建一个内存缓冲区 其大小为1024*1024字节  即1Mbyte[] 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);// 从列表中移除被中断的连接IPlistBox1.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显示长度,如不显示文字可以为0string 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语音转换为Ansispeakbytes = 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);//显示文字转换为Ansifor (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显示长度,如不显示文字可以为0string 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语音转换为Ansispeakbytes = 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);//显示文字转换为Ansifor (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.rhkb.cn/news/184205.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EM@解三角形@正弦定理@余弦定理

文章目录 abstract解三角形基本原理不唯一性 正弦定理直角三角形中的情形推广锐角三角形钝角情形 小结:正弦定理 余弦定理直角三角形中的情形非直角情形小结:余弦定理公式的角余弦形式 abstract 解直角三角形问题正弦定理和余弦定理的推导 对于非直角情形,都是直角情形的推广同…

机器视觉的试卷批改系统 - opencv python 视觉识别 计算机竞赛

文章目录 0 简介1 项目背景2 项目目的3 系统设计3.1 目标对象3.2 系统架构3.3 软件设计方案 4 图像预处理4.1 灰度二值化4.2 形态学处理4.3 算式提取4.4 倾斜校正4.5 字符分割 5 字符识别5.1 支持向量机原理5.2 基于SVM的字符识别5.3 SVM算法实现 6 算法测试7 系统实现8 最后 0…

微服务架构深入理解 | 技术栈

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; 微服务架构深入理解 | 技术栈 服务网关 服务网关是在微服务架构中扮演重要角色的组件&#xff0c;它是系统对外的入口&#xff0c;负责接收和处理客户端的请求&#x…

【算法 | 模拟No.3】leetcode 38. 外观数列

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【Leetcode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

鸿蒙原生应用开发-DevEco Studio超级终端模拟器的使用

一、了解超级终端模拟器支持的设备情况 该特性在DevEco Studio V2.1 Release及更高版本中支持。 目前超级终端模拟器支持“PhonePhone”、“PhoneTablet”和“PhoneTV”的设备组网方式&#xff0c;开发者可以使用该超级终端模拟器来调测具备跨设备特性的应用/服务&#xff0c;如…

中远麒麟堡垒机SQL注入漏洞复现

简介 中远麒麟堡垒机用于运维管理的认证、授权、审计等监控管理&#xff0c;在该产品admin.php处存在SQL 注入漏洞。 漏洞复现 FOFA语法&#xff1a; body"url\"admin.php?controlleradmin_index&actionget_user_login_fristauth&username" 或者 c…

redis: 记录一次线上redis内存占用过大问题解决过程

引言 记录一次线上redis占用过大的排查过程&#xff0c;供后续参考 问题背景 测试同事突然反馈测试环境的web系统无法登陆&#xff0c;同时发现其他子系统也存在各类使用问题 排查过程 1、因为首先反馈的是测试环境系统无法登陆&#xff0c;于是首先去查看了登陆功能的报错…

【STM32】HAL库UART含校验位的串口通信配置BUG避坑

【STM32】HAL库UART含校验位的串口通信配置BUG避坑 文章目录 UART协议校验位HAL库配置含校验位的串口配置BUG避坑附录&#xff1a;Cortex-M架构的SysTick系统定时器精准延时和MCU位带操作SysTick系统定时器精准延时延时函数阻塞延时非阻塞延时 位带操作位带代码位带宏定义总线函…

Vuex状态管理(简单易懂、全网最全)

目录 Vuex是什么&#xff1f; 如何部署 如何使用 state 基础使用 在计算属性属性中使用 使用展开运算符 mutations 基础使用 使用辅助函数&#xff08;mapMutations&#xff09;简化 使用常量替代 Mutation 事件类型 getters actions 使用辅助函数&#xff08;…

启动Hbase出现报错

报错信息&#xff1a;slave1:head: cannot open/usr/local/hbase-2.3.1/bin/../logs/hbasewanggiqi-regionserver-slavel.out’ for reading: No such file or direslave2: head: cannot open/usr/local/hbase-2.3.1/bin/../logs/hbasewangqiqi-regionserver-slave2.out’ for …

计算机毕业论文内容参考|基于spingboot的金融投资顾问推荐系统

文章目录 导文文章重点摘要前言绪论课题背景:国内外现状与趋势:课题内容:相关技术与方法介绍系统分析系统设计系统实现总结与展望1本文总结2后续工作展望导文 计算机毕业论文内容参考|基于spingboot的金融投资顾问推荐系统 文章重点 摘要 基于SpingBoot的金融投资顾问推荐…

汽车生产RFID智能制造设计解决方案与思路

汽车行业需求 汽车行业正面临着快速变革&#xff0c;传统的汽车制造方式正在向柔性化、数字化、自动化和数据化的智能制造体系转变&#xff0c;在这个变革的背景下&#xff0c;汽车制造企业面临着物流、生产、配送和资产管理等方面的挑战&#xff0c;为了应对这些挑战&#xf…

ch579串口编程笔记

“CH579SFR.h”库文件&#xff0c;关于串口中断部分 /* UART interrupt identification values for IIR bits 3:0 */ #define UART_II_SLV_ADDR 0x0E // RO, UART0 slave address match #define UART_II_LINE_STAT 0x06 // R…

PTE SST和RL模板

目录 事实证明&#xff0c;SST分值占比很小&#xff0c;不是很需要好好练 SST的模板&#xff1a; RL模板&#xff1a; 给你一个模版供参考&#xff1a; RA技巧 为什么说日本人团结 This lecture mainly talked about the importance of words and the sound of words and…

10道高频webpack面试题快问快答

面试中的快问快答 快问快答的情景在面试中非常常见。 在面试过程中&#xff0c;面试官通常会使用快问快答的方式来快速评估面试者的基础知识、思维能力和反应速度。 这种情景下&#xff0c;面试官会提出一系列简短的问题&#xff0c;并期望面试者能够迅速做出回答或提供简洁明…

在微信小程序中怎么实现报名功能

在当今数字化时代&#xff0c;微信小程序已经成为各行各业进行营销和客户管理的必备工具。其中&#xff0c;报名功能作为微信小程序的一个重要应用场景&#xff0c;为企业或组织提供了方便、高效、实时的数据收集与管理方式。本文将为你详细介绍如何在微信小程序中实现报名功能…

MathType2024优秀的数学公式编辑工具

数学是许多学科中必不可少的一部分&#xff0c;而数学公式在学术和科学领域使用广泛。然而&#xff0c;许多人在创建和编辑数学公式时面临困难。 作为软件开发人员&#xff0c;在编写技术文档时通常也会需要输入一些复杂数学、物理公式&#xff0c;而 Word 中的公式编辑有时使…

阿里开源中间件一览

1. 概述以及竞品对比 间件介绍官方链接竞品竞品介绍异同点对比Dubbo高性能的RPC框架&#xff0c;用于实现分布式服务的调用和管理。DubbogRPC gRPC是由Google开源的一款高性能、通用的RPC框架&#xff0c;支持多种编程语言 链接&#xff1a;gRPC Dubbo更注重于服务治理和可扩展…

【Web】在前端中CSS的语法

CSS规则是由两个主要的部分构成&#xff1a;选择器、以及一条或多条声明。 选择器通常是需要改变的HTML元素。 每条声明由一个属性和一个值组成。 属性&#xff08;Property&#xff09;是需要设置的样式属性&#xff08;Style attribute&#xff09;。每一个属性有一个值。…

峰回网关数采PLC

1.网络配置 例如&#xff1a;plc地址是192.168.1.56 1.访问网关 峰回网关默认网关地址 192.168.3.18&#xff0c;或者&#xff08;10.10.253.354&#xff09;&#xff0c;本案例按照3.18讲解。 1和1相连&#xff0c;0和电脑相连 本地电脑修改ip为192.168.3.3&#xff08;和3…