当前位置: 首页 > news >正文

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 = "开启服务器";}}}
}

相关文章:

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

本示例使用设备介绍&#xff1a;液显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 Sy…...

【electron】【附排查清单】记录一次逆向过程中,fetch无法请求http的疑难杂症(net::ERR_BLOCKED_BY_CLIENT)

▒ 目录 ▒ &#x1f6eb; 导读需求开发环境 1️⃣ Adblock等插件拦截2️⃣ 【失败】Content-Security-Policy启动服务器json-serverhtml中的meta字段 3️⃣ 【失败】https vs httpwebPreferences & allowRunningInsecureContent disable-features 4️⃣ 【失败】检测fetch…...

【JS】scrollTop+scrollHeight+clientTop+clientHeight+offsetTop+offsetHeight

scrollTop、scrollHeight、clientTop、clientHeight、offsetTop以及offsetHeight 1. scrollTop 与 scrollHeight 1.1 scrollTop scrollTop 是这六个属性中唯一一个可写的属性。 Element.scrollTop 属性可以获取或设置一个元素的内容垂直滚动的像素数。 一个元素的 scrollT…...

Go语言函数用法

文章目录 Go语言函数用法 Go语言函数用法 函数在Go语言中有多种用法&#xff0c;它们是组织和模块化代码、提高代码的可维护性和可重用性的关键部分。以下是函数的一些常见用法&#xff1a; 封装代码&#xff1a;函数允许将一组相关的代码块封装到一个独立的单元中&#xff0c…...

3.5、Linux:命令行git的使用

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 在Linux Centos7.6下安装git yum -y install git 注册一个gitee账号 进去注册就好&#xff0c;记住自己的用户名和密码。 创建一个仓库 点击复制&#xff0c;接着就可以在Linux上使用了 git clone git clone 刚才复制的地…...

基于servlet+jsp+mysql网上书店系统

基于servletjspmysql网上书店系统 一、系统介绍二、功能展示四、其它1.其他系统实现五.获取源码 一、系统介绍 项目类型&#xff1a;Java web项目 项目名称&#xff1a;基于servletjspmysql网上书店系统 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 前端技…...

自用工具类整理

自动生成数据 uuid&雪花id private static Long workerId 1L; private static Long datacenterId 1L; private static Snowflake snowflake IdUtil.createSnowflake(workerId, datacenterId);public static String getId(String idType) {if (idType.equals("uui…...

jenkins2

jenkins插件管理安装&#xff1a;docker-build jenkins安装了docker 配置docke builder 添加 unix:///var/run/docker.sock rootubuntu20:~# usermod -G docker jenkins 修改docker中service文件添加 -H tcp://0.0.0.0:2376 jenkins中系统管理中 tcp://localhost:2376...

YOLOv5独家改进:分层特征融合策略MSBlock | 南开大学提出YOLO-MS |超越YOLOv8与RTMDet,即插即用打破性能瓶颈

💡💡💡本文独家改进:分层特征融合策略MSBlock,不同Kernel-Size卷积在不同尺度提升特征提取能力,最终引入到YOLOv5,做到二次创新 1)MSBlock使用;2)和C3结合使用 推荐指数:5颗星 MSBlock | 亲测在多个数据集能够实现大幅涨点,小目标检测效果也不错 💡💡…...

HTTP 协议详解-上(Fiddler 抓包演示)

文章目录 HTTP 协议HTTP 协议的工作过程HTTP 请求 (Request)认识URL关于 URL encode认识 "方法" (method)GET 方法POST 方法其他方法请求 "报头" (header)请求 "正文" (body) HTTP 响应详解状态码响应 "报头" (header) HTTP 协议 HTT…...

龙迅LT8911EXB功能概述 MIPICSI/DSI TO EDP

LT8911EXB 描述&#xff1a; Lontium LT8911EXB是MIPIDSI/CSI到eDP转换器&#xff0c;单端口MIPI接收器有1个时钟通道和4个数据通道&#xff0c;每个数据通道最大运行2.0Gbps&#xff0c;最大输入带宽为8.0Gbps。转换器解码输入MIPI RGB16/18/24/30/36bpp、YUV422 16/20/24bp…...

EtherCAT主站SOEM -- 5 -- SOEM之ethercatdc.h/c文件解析

EtherCAT主站SOEM -- 5 -- SOEM之ethercatdc.h/c文件解析 一 ethercatdc.h/c文件功能预览:二 ethercatdc.h/c 文件的主要函数的作用:2.1.1 函数:`ec_configdc()`2.1.2 函数:`ec_dcsync0(uint16 slave, boolean act, uint32 CyclTime, int32 CyclShift)`2.1.3 函数:`ec_dcs…...

【分布式事务】深入探索 Seata 的四种分布式事务解决方案的原理,优缺点以及在微服务中的实现

文章目录 前言一、XA 模式1.1 XA 模式原理1.2 XA 模式的优缺点及应用场景1.3 Seata XA 模式在微服务中的实现 二、AT 模式2.1 Seata AT 模式原理2.2 AT 模式的脏写问题和写隔离3.3 AT 模式的优缺点3.4 Seata AT 模式在微服务中的实现 三、TCC 模式3.1 TCC 模式原理3.2 Seata 的…...

C语言 || volatile

在C语言中&#xff0c;volatile是一个关键字&#xff0c;用于告诉编译器某个变量是易变的&#xff08;即可能会被程序以外的因素修改&#xff09;&#xff0c;从而告诉编译器不要对该变量进行优化&#xff0c;以确保程序的正确性。 volatile常用于以下几种情况&#xff1a; 并…...

网络安全之CSRF漏洞原理和实战,以及CSRF漏洞防护方法

一、引言 总体来说CSRF属于一种欺骗行为&#xff0c;是一种针对网站的恶意利用&#xff0c;尽管听起来像跨站脚本&#xff08;XSS&#xff09;&#xff0c;但是与XSS非常不同&#xff0c;并且攻击方式几乎向佐。XSS利用站点内的信任用户&#xff0c;而CSRF则通过伪装来自受信任…...

vivo 网络端口安全建设技术实践

作者&#xff1a;vivo 互联网安全团队 - Peng Qiankun 随着互联网业务的快速发展&#xff0c;网络攻击的频率和威胁性也在不断增加&#xff0c;端口是应用通信中的门户&#xff0c;它是数据进出应用的必经之路&#xff0c;因此端口安全也逐渐成为了企业内网的重要防线之一&…...

[ Linux Busybox ] flash_eraseall 命令解析

文章目录 相关结构体flash_eraseall 函数实现flash_eraseall 实现流程图 文件路径&#xff1a;busybox-1.20.2/miscutils/flash_eraseall.c 相关结构体 MTD 相关信息结构体 struct mtd_info_user {__u8 type; // MTD 设备类型__u32 flags; // MTD设…...

RabbitMQ 消息中间件 消息队列

RabbitMQ1、RabbitMQ简介2、RabbitMQ 特点3、什么是消息队列4、RabbiMQ模式5、集群中的基本概念 单实例安装RabbitMQ安装依赖安装erlang安装rabbitmq开启rabbitmq的web访问界面添加用户修改配置文件重启服务浏览器访问Rabbit-test rabbitMQ集群准备工作&#xff08;三台&#x…...

ChatGPT王炸升级GPT-4 Turbo:更强大还更便宜

11月7日&#xff0c;OpenAI首届开发者大会如期召开&#xff0c;在大会上OpenAI正式推出了GPT-4 Turbo。 据OpenAI介绍&#xff0c;相比于GPT-4&#xff0c;GPT-4 Turbo主要有6方面的提升&#xff1a; 第一&#xff0c;上下文对话长度&#xff0c;GPT4最大只能支持8k的上下文长…...

3.JMeter高级使用-让你与众不同

目录 概述插件下载与安装插件下载配置插件 服务器硬件资源监控(精简版)配置服务端代理JMeter配置监控CPU监控网络 JMeter下载结束 概述 今日目标&#xff1a; 插件下载与安装Basic Graphs 主要点 Average Response Time 平均响应时间Active Threads 活动线程数Successful/Fai…...

考研408-计算机网络 第一章-计算机网络体系结构学习笔记及习题

第一章 计算机网络体系结构 一 计算机网络概述 1.1 概念及功能 1.1.1 计算机网络的概念 计算机网络就是互连的、自治的计算机系统的集合 互连&#xff1a;通过通信链路互联互通 自治&#xff1a;各个节点之间无主从关系&#xff0c;高度自治的 1.1.2 计算机网络的功能 功…...

【快速使用ShardingJDBC的哈希分片策略进行分库分表】

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容&#x1f34a;1.引入maven依赖&#x1f34a;2.启动类上添加注解MapperScan&#x1f34a;3.添加application.properties配置&#x1f34a;4.普通的自定义实体类&#x1f34a;5.写个测试类验证一下&#x1f34a;6.控制台打印…...

102. 二叉树的层序遍历

原题链接&#xff1a;102. 二叉树的层序遍历 以下代码为模板&#xff0c;需要层序遍历时都可以使用该模板进行代码更改 全代码&#xff1a; class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {//创建一个TreeNode* 队列用于存储树中的每…...

macOS磁盘分区调整软件--Paragon Camptune X 中文

Paragon Camptune X是一款专为Mac用户设计的强大分区大小调整工具。通过它&#xff0c;用户可以简便地调整Mac硬盘上的分区大小&#xff0c;实现存储空间的高效管理。无论是需要在Mac和Windows系统之间切换的双系统用户&#xff0c;还是有其他特定存储需求的用户&#xff0c;Ca…...

kaggle中报错NameError: name ‘q_1‘ is not defined

在开始练习之前&#xff0c;先点击“全部运行”按钮。...

SQL注入漏洞 其他注入

文章目录 宽字节注入案例 HTTP头部注入Cookie注入base64User-Agent注入Referer 注入 SQL注入读写文件条件1.是否拥有读写权限2.文件路径3.secure_file_priv 读取文件写入文件 SQLMap安装sqlmapkail 源安装仓库克隆 参数简介快速入门&#xff1b;SQLmap&#xff08;常规&#xf…...

Java自学第2课:Java语言基础知识要点

1 Java主类结构 任务&#xff1a;创建新项目名为item&#xff0c;包名为number&#xff0c;类名为first。 1.1 包声明 不指定包时&#xff0c;默认就是工程名&#xff0c;指定后&#xff0c;类文件可以分类了&#xff0c;是这意思吧。包就大概等于一个文件夹。而且在类文件中…...

flink状态和检查点

检查点和状态后端的区别 检查点 就是某个时间点下的所有算子的状态快照。这个时间点就是等所有任务将“同一个数据”处理完毕的时候。 状态后端&#xff1a;是一个管理状态的组件&#xff0c;还负责将本地状态&#xff08;检查点&#xff09;持久化到远程文件存储系统中。 分…...

数据仓库工具箱-零售业务

文章目录 一、维度模型设计的4步过程1.1 第一步&#xff1a;选择业务过程1.2 第二步&#xff1a;声明粒度1.3 第三步&#xff1a;确定维度1.4 第四步&#xff1a;确定事实 二、零售业务案例研究2.1 第一步&#xff1a;选择业务过程2.2 第二步&#xff1a;声明粒度2.3 第三步&am…...

网络工程实验记录

网络工程 show ip route show running-config 第一周 相同设备使用交叉线&#xff0c;不同设备之间使用直通线 R1能ping通10.1.1.1 R2能ping通所有的 R3能ping通172.16.1.1 即路由器只能到达自身线连接出去的&#xff0c;另一端就连接不了了。 此时给R1分配静态路由 R…...