/* * 该类用于管理tcp连接通讯 */ using System; using System.Collections.Generic; using System.Net.Sockets; using System.Threading; using System.Net; namespace HDL_ON.DAL.Net { /// /// 服务端 /// public class TcpListener { private Socket ServerSocket = null;//服务端 public Dictionary dic_ClientSocket = new Dictionary();//tcp客户端字典 private Dictionary dic_ClientThread = new Dictionary();//线程字典,每新增一个连接就添加一条线程 private bool Flag_Listen = true;//监听客户端连接的标志 /// /// 启动服务 /// /// 端口号 public bool OpenServer(int port) { try { Flag_Listen = true; // 创建负责监听的套接字,注意其中的参数; ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 创建包含ip和端口号的网络节点对象; IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, port); try { // 将负责监听的套接字绑定到唯一的ip和端口上; ServerSocket.Bind(endPoint); } catch { return false; } // 设置监听队列的长度; ServerSocket.Listen(100); // 创建负责监听的线程; Thread Thread_ServerListen = new Thread(ListenConnecting); Thread_ServerListen.IsBackground = true; Thread_ServerListen.Start(); MainPage.Log("启动tcp侦听"); return true; } catch { return false; } } /// /// 关闭服务 /// public void CloseServer() { lock (dic_ClientSocket) { foreach (var item in dic_ClientSocket) { item.Value.Close();//关闭每一个连接 } dic_ClientSocket.Clear();//清除字典 } lock (dic_ClientThread) { foreach (var item in dic_ClientThread) { item.Value.Abort();//停止线程 } dic_ClientThread.Clear(); } Flag_Listen = false; //ServerSocket.Shutdown(SocketShutdown.Both);//服务端不能主动关闭连接,需要把监听到的连接逐个关闭 if (ServerSocket != null) ServerSocket.Close(); } /// /// 监听客户端请求的方法; /// private void ListenConnecting() { while (Flag_Listen) // 持续不断的监听客户端的连接请求; { try { Socket sokConnection = ServerSocket.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字; // 将与客户端连接的 套接字 对象添加到集合中; string str_EndPoint = sokConnection.RemoteEndPoint.ToString(); MySession myTcpClient = new MySession() { TcpSocket = sokConnection }; //创建线程接收数据 Thread th_ReceiveData = new Thread(ReceiveData); th_ReceiveData.IsBackground = true; th_ReceiveData.Start(myTcpClient); //把线程及客户连接加入字典 dic_ClientThread.Add(str_EndPoint, th_ReceiveData); dic_ClientSocket.Add(str_EndPoint, myTcpClient); } catch { } Thread.Sleep(200); } } /// /// 接收数据 /// /// private void ReceiveData(object sokConnectionparn) { MySession tcpClient = sokConnectionparn as MySession; Socket socketClient = tcpClient.TcpSocket; bool Flag_Receive = true; while (Flag_Receive) { try { // 定义一个2M的缓存区; byte[] arrMsgRec = new byte[1024 * 1024 * 2]; // 将接受到的数据存入到输入 arrMsgRec中; int length = -1; try { length = socketClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度; } catch (Exception ex) { MainPage.Log($"tcpListener error 1 : {ex.Message}"); Flag_Receive = false; // 从通信线程集合中删除被中断连接的通信线程对象; string keystr = socketClient.RemoteEndPoint.ToString(); dic_ClientSocket.Remove(keystr);//删除客户端字典中该socket dic_ClientThread[keystr].Abort();//关闭线程 dic_ClientThread.Remove(keystr);//删除字典中该线程 tcpClient = null; socketClient = null; break; } byte[] buf = new byte[length]; Array.Copy(arrMsgRec, buf, length); lock (tcpClient.m_Buffer) { var tcpDataString = System.Text.Encoding.UTF8.GetString(buf); AnalysisTcpData(tcpDataString); MainPage.Log(tcpDataString); } } catch (Exception ex) { MainPage.Log($"tcpListener error 2 : {ex.Message}"); } Thread.Sleep(100); } } /// /// 处理tcp数据 /// void AnalysisTcpData(string tcpDataString) { var obj = Newtonsoft.Json.JsonConvert.DeserializeObject(tcpDataString); if(obj == null) { return; } var tcpCommand = obj.GetValue("command").ToString(); var tcpType = obj.GetValue("type").ToString(); switch (tcpCommand) { /* case "search":// 适用于搜索 case "get_list"://获取列表 case "set_list":// 修改列表 case "write":// 用于依次控制相关类型信息 case "delete":// 用于删除相关操作 case "initialize":// 初始化 case "find":// 设备定位 case "get":// 用于获取sid当前状态 case "set":// 用于控制sid相关参数 */ case "add":// 用于增加功能 switch (tcpType) { case "device_oid":// 用于原生态设备读写相关操作 var addFunction = Newtonsoft.Json.JsonConvert.DeserializeObject>(obj.GetValue("objects").ToString()); break; case "device_sid": var addSidFunction = Newtonsoft.Json.JsonConvert.DeserializeObject(tcpDataString); break; } break; case "read":// 用于依次读取相关类型信息状态 switch (tcpType) { /* case "space":// 适用于全部设备, 获取空间信息 case "device":// 网关或者其他A设备 case "device_mac":// 用于设备机身号码相关操作 case "scene":// 用于场景功能读写 case "security":// 用于安防功能读写 case "remote":// 用于远程信息读写操作 case "logic":// 用于逻辑自动化读写操作 case "global":// 用于组播搜索A设备 */ case "device_oid":// 用于原生态设备读写相关操作 Dictionary dic_oid = new Dictionary(); dic_oid.Add("from_oid", null); dic_oid.Add("to_oid", null); dic_oid.Add("time_stamp", null); dic_oid.Add("type", "device_oid"); dic_oid.Add("command", "get_list_response"); List oidObjList = new List(); foreach (var d01 in Entity.DB_ResidenceData.residenceData.functionList.GetAllDeviceFunctionList()) { Dictionary d0 = new Dictionary(); d0.Add("oid", d01.sid); d0.Add("status", "online"); d0.Add("device_name", d01.name); d0.Add("device_model","HDL MD0602.523"); d0.Add("device_mac", "123456789067890"); d0.Add("hw_info", "STM32F104"); d0.Add("fw_version","HDL_V04.01U"); oidObjList.Add(d0); } dic_oid.Add("objects", oidObjList); Newtonsoft.Json.JsonConvert.SerializeObject(dic_oid); break; case "device_sid":// 用于功能模型读写操作 Dictionary dic_sid = new Dictionary(); dic_sid.Add("from_oid", null); dic_sid.Add("to_oid", null); dic_sid.Add("time_stamp", null); dic_sid.Add("type", "device_sid"); dic_sid.Add("command", "get_list_response"); List sidObjList = new List(); foreach (var d01 in Entity.DB_ResidenceData.residenceData.functionList.GetAllDeviceFunctionList()) { Dictionary d0 = new Dictionary(); d0.Add("sid", d01.sid); d0.Add("name", d01.name); d0.Add("type", d01.functionType); sidObjList.Add(d0); } dic_sid.Add("objects", sidObjList); Newtonsoft.Json.JsonConvert.SerializeObject(dic_sid); break; } break; } } /// /// 发送数据给指定的客户端 /// /// 客户端套接字 /// 发送的数组 /// public bool SendData(string _endPoint, byte[] _buf) { MySession myT = new MySession(); if (dic_ClientSocket.TryGetValue(_endPoint, out myT)) { myT.Send(_buf); return true; } else { return false; } } } /// /// 会话端 /// public class MySession { public Socket TcpSocket;//socket对象 public List m_Buffer = new List();//数据缓存区 public MySession() { } /// /// 发送数据 /// /// public void Send(byte[] buf) { if (buf != null) { TcpSocket.Send(buf); } } /// /// 获取连接的ip /// /// public string GetIp() { IPEndPoint clientipe = (IPEndPoint)TcpSocket.RemoteEndPoint; string _ip = clientipe.Address.ToString(); return _ip; } /// /// 关闭连接 /// public void Close() { TcpSocket.Shutdown(SocketShutdown.Both); } /// /// 提取正确数据包 /// public byte[] GetBuffer(int startIndex, int size) { byte[] buf = new byte[size]; m_Buffer.CopyTo(startIndex, buf, 0, size); m_Buffer.RemoveRange(0, startIndex + size); return buf; } /// /// 添加队列数据 /// /// public void AddQueue(byte[] buffer) { m_Buffer.AddRange(buffer); } /// /// 清除缓存 /// public void ClearQueue() { m_Buffer.Clear(); } } public class TcpAddFunctionOidObject { public string oid; public string name; public string machine_id; public string net_id; public string dev_id; public string channels; } public class TcpAddFunctionSidObject { SidObject objects = new SidObject(); public string type;//device_sid public string from_oid;//": null, public string to_oid;//": null, public string time_stamp;//": null, public string command;//": "add" } public class SidObject { List function = new List(); public string sid;//": "000101E10FEB7212040100010700", public string name;//": "HVAC-1" } }