当前位置: 首页 > 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…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...