using System; using System.Net.Sockets; using System.Net; using System.Collections.Generic; using System.Collections; using System.Threading; using HuizhongLibrary.Log; using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Security.Cryptography; namespace HuizhongLibrary.Network { /// /// Represents a callback used to inform a listener that a ServerConnection has received data. /// /// The sender of the callback. /// The DataEventArgs object containging the received data. public delegate void DataReceivedCallback(ServerConnection sender, DataEventArgs e); /// /// Represents a callback used to inform a listener that a ServerConnection has disconnected. /// /// The sender of the callback. /// The SocketAsyncEventArgs object used by the ServerConnection. public delegate void DisconnectedCallback(ServerConnection sender, SocketAsyncEventArgs e); /// /// A connection to our server. /// public class ServerConnection { public string IpAddress { get; set; } public int Port { get; set; } public string DeviceNo { get; set; } public DateTime PrevTime { get; set; } public List SocketBuffer { get; set; } public SocketMessages ListMessage { get; set; } public bool Enabled { get; set; } public bool IsLogin { get; set; } public string ConnectIp { get; set; } public int ConnectPort { get; set; } public int FileLength { get; set; } public int ReceiveLen { get; set; } public Byte[] Data { get; set; } public string BuffData { get; set; } public int RefshSecond { get; set; } public bool IsSyncSend { get; set; } public int CheckConnectNumber { get; set; } //连接状态验证次数 public int WaitMsgNumber = 0; public bool IsWebSocket = false; //WebSocket握手协议是否完成 public FileStream fs = null; private int MaxSendNumber = 0; private int MaxWaitMsgNumber = 0; private DateTime CacheDataTime = DateTime.Now; public SocketAsyncEventArgs eventArgs; public Socket socket; public event Action SendCompleted; public event Action DataReceived; public event Action CloseSocketed; #region 初始化 public ServerConnection() { CheckConnectNumber = 3; FileLength = 0; IsLogin = false; PrevTime = DateTime.Now; WaitMsgNumber = 0; SocketBuffer = new List(); ListMessage = new SocketMessages(); //Data = new byte[2048]; } public ServerConnection(Socket socket, SocketAsyncEventArgs args) { //Data = new byte[2048]; FileLength = 0; IsLogin = false; PrevTime = DateTime.Now; WaitMsgNumber = 0; SocketBuffer = new List(); ListMessage = new SocketMessages(); if (socket.AddressFamily == AddressFamily.InterNetwork || socket.AddressFamily == AddressFamily.Unspecified) { string[] RemoteEndPoint = socket.RemoteEndPoint.ToString().Split(':'); this.IpAddress = RemoteEndPoint[0]; this.Port = Convert.ToInt32(RemoteEndPoint[1]); ErrorFollow.TraceWrite("请求连接", "", IpAddress); //this.DeviceNo = this.IpAddress.Split(Convert.ToChar("."))[3]; } else { this.IpAddress = ""; } this.Enabled = true; this.socket = socket; eventArgs = args; eventArgs.Completed += ReceivedCompleted; ListenForData(eventArgs); } #endregion #region 连接 public void Start(Socket socket, SocketAsyncEventArgs args) { if (socket.AddressFamily == AddressFamily.InterNetwork || socket.AddressFamily == AddressFamily.Unspecified) { string[] RemoteEndPoint = socket.RemoteEndPoint.ToString().Split(':'); this.IpAddress = RemoteEndPoint[0]; this.Port = Convert.ToInt32(RemoteEndPoint[1]); } else { this.IpAddress = ""; } this.Enabled = true; if (this.socket != null) this.socket = null; if (this.eventArgs != null) { eventArgs.Dispose(); eventArgs = null; } this.socket = socket; eventArgs = args; eventArgs.Completed += ReceivedCompleted; ListenForData(eventArgs); } #endregion #region 返回要发送的消息 public SocketMessage GetNextSocketMessage(int RefshSecond) { var item=ListMessage.GetNextSocketMessage(RefshSecond); if (item == null) return null; if (item.SendNumber > 0) { ErrorFollow.TraceWrite("重发", "", item.FunNo); DecrementWaitMsgNumber(); } return item; } #endregion #region 移除已发送消息 public void RemoveSocketMessage() { ListMessage.RemoveEmploy(); } #endregion #region 增加等待回复的消息数 public void IncrementWaitMsgNumber() { Interlocked.Increment(ref WaitMsgNumber); } #endregion #region 减少等待回复的消息数 public void DecrementWaitMsgNumber() { Interlocked.Decrement(ref WaitMsgNumber); //Interlocked.Exchange(ref 变量,11); } #endregion、 #region 消除已回复消息 public SocketMessage EndWaitMsg(string SequenceID) { try { DecrementWaitMsgNumber(); SocketMessage msg = ListMessage.CheckOut(SequenceID); return msg; } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); } return null; } #endregion #region 消除已回复消息 public SocketMessage EndFirstWaitMsg() { try { DecrementWaitMsgNumber(); SocketMessage msg = ListMessage.CheckOut(); return msg; } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); } return null; } #endregion #region 返回消息 public SocketMessage GetSocketMessage(string SequenceID) { return ListMessage.GetSocketMessage(SequenceID); } #endregion #region 合并缓存数据 public void AddData(byte[] RevData, int Offset, int Len) { try { if (CacheDataTime.AddSeconds(15) < DateTime.Now) { SocketBuffer.Clear(); } this.ReceiveLen = Len + SocketBuffer.Count; if (Data.Length < this.ReceiveLen) Data = new byte[ReceiveLen]; for (int i = 0; i < SocketBuffer.Count; i++) { Data[i] = SocketBuffer[i]; } Buffer.BlockCopy(RevData, Offset, Data, SocketBuffer.Count, Len); SocketBuffer.Clear(); } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); } } #endregion #region 新增缓存 public void AddBuff(byte[] SrcArray, int offset) { try { for (int i = offset; i < ReceiveLen; i++) { SocketBuffer.Add(SrcArray[i]); } CacheDataTime = DateTime.Now; } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); } } #endregion #region 清理内存 public void Dispose() { if (SocketBuffer != null) SocketBuffer.Clear(); SocketBuffer = null; if (ListMessage!=null) ListMessage.Clear(); ListMessage = null; } #endregion #region 打包服务器数据 /// /// 打包服务器数据 /// /// 数据 /// 数据包 public static byte[] PackData(string message) { byte[] contentBytes = null; byte[] temp = Encoding.UTF8.GetBytes(message); if (temp.Length < 126) { contentBytes = new byte[temp.Length + 2]; contentBytes[0] = 0x81; contentBytes[1] = (byte)temp.Length; Array.Copy(temp, 0, contentBytes, 2, temp.Length); } else if (temp.Length < 0xFFFF) { contentBytes = new byte[temp.Length + 4]; contentBytes[0] = 0x81; contentBytes[1] = 126; contentBytes[2] = (byte)(temp.Length >> 8 & 0xFF); contentBytes[3] = (byte)(temp.Length & 0xFF); Array.Copy(temp, 0, contentBytes, 4, temp.Length); } else { // 暂不处理超长内容 } return contentBytes; } #endregion #region Public Methods /// /// Disconnects the client. /// public void Disconnect() { lock (this) { CloseConnection(eventArgs); } } /// /// Sends data to the client. /// /// The data to send. /// The offset into the data. /// The ammount of data to send. public bool SendData(Byte[] data, Int32 offset, Int32 count) { try { lock (this) { if (socket.Connected == false) return false; //bool bk=socket.Poll(-1, SelectMode.SelectWrite); this.PrevTime = DateTime.Now; int i = socket.Send(data, offset, count, SocketFlags.None); if (i <= 0) return false; } } catch (Exception ex) { return false; } return true; } #region WebSocket专用 public bool SendData(string data) { lock (this) { if (socket.Connected == false) return false; //bool bk=socket.Poll(-1, SelectMode.SelectWrite); this.PrevTime = DateTime.Now; byte[] bytes = PackData(data); int i = socket.Send(bytes, 0, bytes.Length, SocketFlags.None); if (i <= 0) return false; } return true; } #endregion #endregion #region 获取Socket public Socket GetSocket() { lock (this) { return socket; } } #endregion #region Private Methods /// /// Starts and asynchronous recieve. /// /// The SocketAsyncEventArgs to use. private void ListenForData(SocketAsyncEventArgs args) { lock (this) { if (socket == null) return; if (socket.Connected) { socket.InvokeAsyncMethod(socket.ReceiveAsync, ReceivedCompleted, args); } } } /// /// Called when an asynchronous receive has completed. /// /// The sender. /// The SocketAsyncEventArgs for the operation. private void ReceivedCompleted(Object sender, SocketAsyncEventArgs args) { try { if (args.BytesTransferred == 0) { if (string.IsNullOrEmpty(this.DeviceNo)==false)Disconnect(); return; } if (args.SocketError != SocketError.Success) { if (string.IsNullOrEmpty(this.DeviceNo) == false) Disconnect(); return; } this.Data = new byte[args.BytesTransferred]; this.ReceiveLen = this.Data.Length; Buffer.BlockCopy(args.Buffer, args.Offset, this.Data, args.Offset, args.BytesTransferred); if (this.DataReceived!=null)this.DataReceived(this, new DataEventArgs() { Data = this.Data, Length = this.ReceiveLen }); ListenForData(args); //if (state.socket.Available == 0) //{ // ListenForData(args); //} } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); Disconnect(); } } #region 输出数据日志 string WaitData(byte[] bytes, int index, int Length) { try { return Encoding.UTF8.GetString(bytes, index, Length); } catch { string a = ""; foreach (var item in bytes) { a += item.ToString("X"); } return a; } } #endregion /// /// Closes the connection. /// /// The SocketAsyncEventArgs for the connection. private void CloseConnection(SocketAsyncEventArgs args) { if (this.Enabled == false)return; this.Enabled = false; this.WaitMsgNumber = 0; if (socket == null) return; try { socket.Shutdown(SocketShutdown.Both); } catch { } try { socket.Close(); } catch { } try { Dispose(); args.Completed -= ReceivedCompleted; //MUST Remember This! socket = null; this.Data = null; } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); } if (this.CloseSocketed != null) this.CloseSocketed(this, args); } #endregion #region Events /// /// Fires the DataReceivedCallback. /// /// The data which was received. /// The address the data came from. /// The callback. private void OnDataReceived(DataReceivedCallback callback) { callback(this, new DataEventArgs() { Data = this.Data, Length = this.ReceiveLen }); } /// /// Fires the DisconnectedCallback. /// /// The SocketAsyncEventArgs for this connection. /// The callback. private void OnDisconnected(SocketAsyncEventArgs args, DisconnectedCallback callback) { callback(this, args); } #endregion } }