using Azylee.Core.ThreadUtils.SleepUtils; using Azylee.Core.WindowsUtils.ConsoleUtils; using Azylee.Jsons; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace Azylee.YeahWeb.SocketUtils.TcpUtils { /// /// Tcp 服务工具 /// public class TcppServer { const int ReceiveBufferSize = 1024; private List ReceiveByte = new List(); private int _Port = 52801; TcpListener Listener = null; Action OnConnectAction = null; Action OnDisconnectAction = null; Action OnReceiveAction = null; public TcpClientManager TcpClientManager = new TcpClientManager(); /// /// 构造函数 /// /// 端口号 /// 连接动作 /// 断开动作 /// 接收消息 public TcppServer(int port, Action onConnect, Action onDisconnect, Action onReceive) { _Port = port; OnConnectAction = onConnect; OnDisconnectAction = onDisconnect; OnReceiveAction = onReceive; } #region 启动和停止服务 /// /// 启动服务 /// public void Start() { this.Listener = new TcpListener(IPAddress.Any, _Port); this.Listener.Start(); this.Listener.BeginAcceptTcpClient(new AsyncCallback(acceptCallback), this.Listener); } /// /// 停止服务 /// public void Stop() { foreach (var client in TcpClientManager.GetAll()) { client?.Client?.Close(); } Listener?.Stop(); } #endregion #region 连接后的读写操作 /// /// 发送数据 /// /// 主机地址 /// 数据模型 public bool Write(string host, TcpDataModel model) { var dictionary = TcpClientManager.GetInfoByHost(host); if (dictionary != null && dictionary.Client != null) { if (dictionary.Client.Connected) { TcpClientManager.UpdateUploadFlowCount(host, model.Data.Length); bool flag = TcpStreamHelper.Write(dictionary.Client, model); return flag; } } return false; } private void acceptCallback(IAsyncResult state) { try { TcpListener lstn = (TcpListener)state.AsyncState; TcpClient client = lstn.EndAcceptTcpClient(state); string host = client.Client.RemoteEndPoint.ToString(); TcpClientManager.AddOrUpdate(host, client); ConnectTask(host, client); lstn.BeginAcceptTcpClient(new AsyncCallback(acceptCallback), lstn); } catch { } } private void ConnectTask(string host, TcpClient client) { TcpClientInfo clientInfo = TcpClientManager.GetInfoByHost(host); //发送心跳 Task.Factory.StartNew(() => { while (client.Connected) { TcpDataModel model = new TcpDataModel(int.MaxValue); TcpStreamHelper.Write(client, model); Sleep.S(5); //if (DateTime.Now.AddSeconds(-10) > HeartbeatTime) // client.Close(); Sleep.S(5); } }); //接收消息 Task.Factory.StartNew(() => { OnConnectAction?.Invoke(clientInfo);//委托:已连接 while (client.Connected) { try { TcpDataModel model = TcpStreamHelper.Read(client); if (model != null) { if (model.Type == int.MaxValue) { //过滤心跳,并记录心跳时间 TcpClientManager.UpdateHeartbeatTime(host); } else { TcpClientManager.UpdateDownloadFlowCount(host, model.Data.Length); OnReceiveAction(clientInfo, model);//委托:接收消息 } } } catch { } //Sleep.S(1); } client.Close(); TcpClientManager.RemoveByHost(host); OnDisconnectAction?.Invoke(clientInfo);//委托:断开连接 }); } #endregion } }