/* * 该类用于管理tcp作为服务端连接通讯 */ using System; using System.Collections.Generic; using System.Net.Sockets; using System.Threading; using System.Net; using Shared; using HDL_ON.Entity; namespace HDL_ON.DriverLayer { /// /// TCP服务端 /// public class Control_TcpServer { 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 = 8586) { 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) { //tcpClient.m_Buffer.Add(buf); var tcpDataString = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, length); if (!string.IsNullOrEmpty(tcpDataString)) { AnalysisTcpData(socketClient, tcpDataString); } MainPage.Log(tcpDataString); } } catch (Exception ex) { MainPage.Log($"tcpListener error 2 : {ex.Message}"); } Thread.Sleep(100); } } /// /// 获取列表数据回调方法 /// public Action GetListResponseAction; string tcpFunctionOidJsonString = ""; /// /// 处理tcp数据 /// void AnalysisTcpData(Socket socket, string tcpBodyDataString) { MainPage.Log($"0001 tcpDataString:\r\n {tcpBodyDataString}"); var tcpDataObj = Control.Ins.AnalysisReceiveData(tcpBodyDataString); if (tcpDataObj.BodyDataString == null) { return; } switch (tcpDataObj.Topic) { case CommunicationTopic.AddDeviceOids: tcpFunctionOidJsonString = tcpDataObj.BodyDataString; break; case CommunicationTopic.AddFunctions: var addSidFunction = Newtonsoft.Json.JsonConvert.DeserializeObject(tcpDataObj.BodyDataString); Application.RunOnMainThread(() => { var tipDialog = new UI.UpdataSidDataDialog(); var tcpLocalFunction = Newtonsoft.Json.JsonConvert.DeserializeObject>(Newtonsoft.Json.JsonConvert.SerializeObject(addSidFunction.objects)); tipDialog.ShowDialog(tcpLocalFunction, tcpFunctionOidJsonString); }); break; case CommunicationTopic.BusPcGetAppOids: var bytes = Common.FileUtlis.Files.ReadFile(DB_ResidenceData.OidSavePathName); if (bytes.Length > 0) { socket.Send(bytes); MainPage.Log($"send oid list to 8586 prot :{ System.Text.Encoding.UTF8.GetString(bytes)}"); } break; case CommunicationTopic.BusPcGetAppSids: var sendSidObj = new TcpTransmissionSidsObj(); sendSidObj.id = Control.Ins.msg_id.ToString(); sendSidObj.time_stamp = ""; //转换成bus需要的数据格式 var localFunction = FunctionList.List.GetDeviceFunctionList(); var localFunctionString = Newtonsoft.Json.JsonConvert.SerializeObject(localFunction); var tcpFunction = Newtonsoft.Json.JsonConvert.DeserializeObject>(localFunctionString); sendSidObj.objects.AddRange(tcpFunction); var sendSidJson = Newtonsoft.Json.JsonConvert.SerializeObject(sendSidObj); var sendSidBytes = System.Text.Encoding.UTF8.GetBytes(sendSidJson); socket.Send(sendSidBytes, sendSidBytes.Length, SocketFlags.OutOfBand); MainPage.Log($"send sid list to 8586 prot :{sendSidJson}"); 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(); } } /// /// bus软件传输功能的sid列表对象 /// public class TcpTransmissionSidsObj { public List objects = new List(); public string id = ""; public string time_stamp = ""; } /// /// bus软件传输的功能对象 /// 仅在与bus软件传递数据时使用, /// Function对象包含了该对象的所有内容, /// 此对象为了减少传输数据使用 /// public class BusSidObj { public string sid = "";// "0301011234567801012301230123"; /// /// A协议功能的属性 /// 如:是AC功能:属性:on_off,mode,fan,temperature /// public List attributes = new List(); /// /// 备注 /// public string name; public string omodel; } }