using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; namespace AGV_WPF.Services { public class SocketTcpServer { private Socket socket; private IPEndPoint IpEndPoint; private bool ListenerBool = false; public Dictionary SocketDic = new Dictionary(); public delegate byte[] DealMessage(Socket SocketClient, byte[] data); public DealMessage ReceiveDataDeal { get; set; } public SocketTcpServer(int Port, string IP = null) { if (IP == null) { IpEndPoint = new IPEndPoint(IPAddress.Any, Port); } else { IpEndPoint = new IPEndPoint(IPAddress.Parse(IP), Port); } } private bool IsConnected(Socket SocketClient) { if (SocketClient == null) return false; if (!SocketClient.Connected) return false; //if (!SocketClient.Poll(1000, SelectMode.SelectRead)) return false; if (!SocketClient.Poll(50, SelectMode.SelectWrite)) return false; if (SocketClient.Poll(50, SelectMode.SelectError)) return false; return true; } private void ListenerClient(int ListenNumber, int TimeOut) { while (ListenerBool) { Socket connectClient = socket.Accept(); if (IsConnected(connectClient)) { Task.Factory.StartNew(() => ReceiveMessage(connectClient, TimeOut)); if (!SocketDic.ContainsKey(connectClient.RemoteEndPoint.ToString())) { SocketDic.Add(connectClient.RemoteEndPoint.ToString(), connectClient); } } Thread.Sleep(200); } } private void ReceiveMessage(Socket SocketClient, int TimeOut, bool ConnectionBool = true) { DateTime timer = DateTime.Now; EndPoint RemoteEndPoint = SocketClient.RemoteEndPoint; while (ConnectionBool && IsConnected(SocketClient)) { try { if (!SocketDic.ContainsKey(RemoteEndPoint.ToString())) { Thread.Sleep(500); continue; } byte[] Data = new byte[1024]; int Length = SocketClient.Receive(Data, 0, Data.Length, SocketFlags.None); if (Length > 0) { byte[] receiveData = new byte[Length]; for (int i = 0; i < Length; i++) { receiveData[i] = Data[i]; } if (ReceiveDataDeal != null) { byte[] sendData = ReceiveDataDeal.Invoke(SocketClient, receiveData); if (sendData != null && sendData.Length > 0) { SendMessage(SocketClient, sendData); } timer = DateTime.Now; } } else if (Length == 0) { ConnectionBool = false; if (SocketClient != null) { SocketClient.Close(); } SocketDic.Remove(RemoteEndPoint.ToString()); } if ((DateTime.Now - timer).TotalMinutes > TimeOut) { ConnectionBool = false; if (SocketClient != null) { SocketClient.Close(); } SocketDic.Remove(RemoteEndPoint.ToString()); } Thread.Sleep(200); } catch (Exception ex) { ConnectionBool = false; if (SocketClient != null) { SocketClient.Close(); } SocketDic.Remove(RemoteEndPoint.ToString()); } } } public bool SendMessage(Socket SocketClient, byte[] Data) { if (IsConnected(SocketClient) && Data.Length > 0) { return SocketClient.Send(Data, 0, Data.Length, SocketFlags.None) > 0; } return false; } public bool StartListener(int ListenNumber, int TimeOut) { try { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(IpEndPoint); ListenerBool = true; socket.Listen(ListenNumber); Task.Factory.StartNew(() => ListenerClient(ListenNumber, TimeOut)); return true; } catch { return false; } } public void CloseListener() { foreach (var item in SocketDic) { item.Value.Close(); } SocketDic.Clear(); ListenerBool = false; if (socket != null) { socket.Close(); } } public bool CloseClientConnection(Socket SocketClient) { if (IsConnected(SocketClient)) { if (SocketDic.ContainsKey(SocketClient.RemoteEndPoint.ToString())) { SocketDic.Remove(SocketClient.RemoteEndPoint.ToString()); } SocketClient.Close(); return true; } return false; } } }