using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Net.Sockets; using System.Net; using F.Studio.Common.Cfg; using System.Collections.Concurrent; namespace KomaxCSTcpServer { public class AcquireServer : IDisposable { private object lockObj = new object(); public String IP { get; private set; } public int Port { get; private set; } //7788 public String Position { get; set; } public TcpListener _Listener = null; private bool IsRuning = false; private bool _Enabled = false; private bool disposed = false; public List<ClientDescription> _ClientList = new List<ClientDescription>(); public event EventHandler<DataReceivedArgs> DataReceived = null; public AcquireServer(string ip, int port) { this.IP = ip; this.Port = port; } public void Start() { if (_Enabled) return; _Enabled = true; ThreadPool.QueueUserWorkItem((o) => { _Start(); }); } private void _Start() { LogInfo("进入工作线程:" + Thread.CurrentThread.ManagedThreadId); while (IsRuning) { Thread.Sleep(1000 * 1); } try { _Listener = new TcpListener(IPAddress.Any, Port); _Listener.Start(); // Enter the listening loop. while (_Enabled) { Console.WriteLine("Waiting for a connection... "); IsRuning = true; // Perform a blocking call to accept requests. // You could also use server.AcceptSocket() here. TcpClient client = _Listener.AcceptTcpClient(); Console.WriteLine("Connected!"); ThreadPool.QueueUserWorkItem(o => { ReceptionClient(client); }, null); } } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); } finally { if (_Listener != null) { try { Console.WriteLine("关闭监听..."); _Listener.Stop(); } catch { } } IsRuning = false; if (_Enabled) { ThreadPool.QueueUserWorkItem((o) => { _Start(); }); } LogInfo("退出工作线程:" + Thread.CurrentThread.ManagedThreadId); } } private void AddToList(ClientDescription client) { lock (lockObj) { if (_ClientList.Any(ent => ent.Equals(client))) return; _ClientList.Add(client); } } private void RemoveFromList(ClientDescription client) { lock (lockObj) { _ClientList.Remove(client); } } /// <summary> /// 发送给全部链接 /// </summary> /// <param name="bytes"></param> public void SendToAllClient(byte[] bytes) { try { lock (lockObj) { foreach (var cd in _ClientList) { if (!cd.IsDead) { cd._Queue4CmdBytes.Enqueue(bytes); } } } } catch (Exception ex) { LogErr(ex); } } /// <summary> /// 发送给最后接入链接 /// </summary> /// <param name="bytes"></param> public void SendToLastConnClient(byte[] bytes) { try { var cd = _ClientList.OrderByDescending(ent => ent.ConnectedTime).FirstOrDefault(); if (cd != null) { if (!cd.IsDead) { cd._Queue4CmdBytes.Enqueue(bytes); } } } catch (Exception ex) { LogErr(ex); } } private void ReceptionClient(TcpClient client) { #region 数据处理 var cd = new ClientDescription(client); cd.RemotePoint = client.Client.RemoteEndPoint as IPEndPoint; cd.LocalPoint = client.Client.LocalEndPoint as IPEndPoint; cd.ConnectedTime = DateTime.Now; cd.LastInterchangeDataTime = DateTime.Now; AddToList(cd); Byte[] buffer = new byte[1024]; int errCount = 0; var _Stream = client.GetStream(); while (_Enabled && cd._Loop) { #region Poll try { #region 数据发送处理 if (cd._Queue4CmdBytes.Count > 0) { byte[] bytes = null; if (cd._Queue4CmdBytes.TryDequeue(out bytes)) { if (_Stream != null) { _Stream.Write(bytes, 0, bytes.Length); //发送成功更新最后交换时间 cd.LastInterchangeDataTime = DateTime.Now; Thread.Sleep(50); } } } #endregion #region 数据接收处理 if (_Stream.DataAvailable) { var len = _Stream.Read(buffer, 0, buffer.Length); if (len <= 0) throw new Exception("收到零长度数据!"); if (len > 0) cd.LastInterchangeDataTime = DateTime.Now; var bytes = new Byte[len]; Array.Copy(buffer, bytes, len); var rawDataStr = Encoding.UTF8.GetString(buffer, 0, len); LogInfo(rawDataStr); if (DataReceived != null) { try { DataReceived(cd, new DataReceivedArgs() { Bytes = bytes, RawStr = rawDataStr,ClientDes=cd }); } catch (Exception ex) { LogErr(ex); } } //HandleReceiveStr(bytes, rawDataStr); errCount = 0; } #endregion #region 超时断开链接 var maxHoldSeconds = SimpleCfgMgr.GetV<int>("ConnMaxHoldSeconds", 120); var checkConnUseHB = SimpleCfgMgr.GetV<bool>("CheckConnUseHB", true); if ((DateTime.Now - cd.LastInterchangeDataTime).TotalSeconds > maxHoldSeconds) { if (checkConnUseHB) { var bytes_HB = Encoding.UTF8.GetBytes(string.Format("$HB:{0}$", DateTime.Now.Ticks)); cd.SendCmd(bytes_HB); } else { cd._Loop = false; } } #endregion Thread.Sleep(10); } catch (Exception ex) { errCount++; if (errCount >= 1) { cd._Loop = false; } LogErr(ex); Thread.Sleep(1000 * 3); } finally { } #endregion } //标记成死链接 cd.IsDead = true; #region 尝试关闭链接--这个会通知已经链接的客户端 try { _Stream.Close(); } catch { } try { client.Close(); } catch { } #endregion RemoveFromList(cd); LogInfo(string.Format("断开与链接{0}:{1}的交互", cd.RemotePoint.Address, cd.RemotePoint.Port)); #endregion } public void Stop() { _Enabled = false; if (_Listener != null) { try { _Listener.Stop(); } catch { } } while (IsRuning) { Thread.Sleep(1000 * 1); } } #region Log private void LogErr(Exception ex) { if (!SimpleCfgMgr.GetV<bool>("LogErr", true)) return; Console.WriteLine(string.Format("[{0}->{1}:{2}] Err:{3}", DateTime.Now.ToString("HH:mm:ss"), IP, Port, ex.Message)); } private void LogInfo(string msg) { if (!SimpleCfgMgr.GetV<bool>("LogInfo", true)) return; Console.WriteLine(string.Format("[{0}->{1}:{2},T:{4}] Info:{3}", DateTime.Now.ToString("HH:mm:ss"), IP, Port, msg, Thread.CurrentThread.ManagedThreadId)); } #endregion #region IDisposable Members /// <summary> /// Performs application-defined tasks associated with freeing, /// releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed /// and unmanaged resources; <c>false</c> /// to release only unmanaged resources. /// </param> protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { try { Stop(); } catch { } } disposed = true; } } #endregion } public class DataReceivedArgs : EventArgs { public ClientDescription ClientDes { get; set; } public Byte[] Bytes { get; set; } public String RawStr { get; set; } } public class ClientDescription { public DateTime ConnectedTime { get; set; } public DateTime LastInterchangeDataTime { get; set; } public IPEndPoint RemotePoint { get; set; } public IPEndPoint LocalPoint { get; set; } public String ClientName { get; set; } public bool IsDead { get; set; } public TcpClient _Client { get; set; } public bool _Loop { get; set; } private NetworkStream _Stream { get; set; } public ConcurrentQueue<byte[]> _Queue4CmdBytes = new ConcurrentQueue<byte[]>(); public ClientDescription(TcpClient client) { _Client = client; _Stream = client.GetStream(); _Loop = true; } public void Close() { _Loop = false; } public void SendCmd(byte[] bytes) { if (!IsDead && _Client != null && _Client.Connected) { _Queue4CmdBytes.Enqueue(bytes); } } } }View Code
标签:set,get,C#,bytes,Tcp,cd,client,Server,public From: https://www.cnblogs.com/wdfrog/p/18363222