using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; namespace TCPManager { /// <summary> /// 处理接收回来的数据,返回处理完的总字节数。 /// </summary> /// <param name="conn"></param> /// <param name="inBuf">从[0] 开始处理</param> /// <returns></returns> public delegate int ParsePacketHandler(TCPConn conn, byte[] inBuf); public class TCPConn { TimeSpan Heartbeat_Interval = TimeSpan.FromSeconds(5); // heartbeat包发送间隔时间,5秒 TimeSpan Silent_Time = TimeSpan.FromSeconds(30); // 单位ms没有收到任何东西的时间,1分钟 const int MAX_BUFFER = 20 * 0x4000;//20个大包, 大包的尺寸在FObjSys 定义 const int Send_Error_timer = 5000; // 5000ms protected List<byte> in_buffer = new List<byte>(MAX_BUFFER); protected int packet_start; protected int packet_len; protected List<byte> out_buffer = new List<byte>(MAX_BUFFER); protected DateTime comm_time; protected DateTime heartbeat_time = DateTime.Now; /// <summary> /// 长时间没发东西事件 /// </summary> public event Action<TCPConn> OutputIsEmptyWithLongTimeEvent; /// <summary> /// 数据接收处理 /// </summary> public ParsePacketHandler ParsePacket = null; public Socket sock; protected bool first_poll = true; public TCPConn() { } public TCPConn(Socket sock) { this.sock = sock; } public virtual int SendPacket(byte[] buffer) { int len = buffer.Length; out_buffer.AddRange(buffer); return len; } protected virtual int Clear_Packet() { if (packet_start > 0) { in_buffer.RemoveRange(0, packet_start); } return in_buffer.Count(); } int Send_Poll2() { if (out_buffer.Count() == 0) { if ((DateTime.Now - heartbeat_time) > Heartbeat_Interval) { if (OutputIsEmptyWithLongTimeEvent != null) OutputIsEmptyWithLongTimeEvent(this); } else return 0; } heartbeat_time = DateTime.Now; return Send_Poll(); } int Send_Poll() { int cnt_total = 0; if (out_buffer.Count() == 0) return 0; while (out_buffer.Count() > 0) { int cnt; try { cnt = sock.Send(out_buffer.ToArray()); } catch (System.Net.Sockets.SocketException e) { if (e.SocketErrorCode == SocketError.WouldBlock) break; return -1; } if (cnt > 0) { out_buffer.RemoveRange(0, cnt); cnt_total += cnt; } else { break; } } return cnt_total; } int Receive_Poll() { int reclen_total = 0; while (true) { int reclen; try { reclen = sock.Available; } catch (System.Net.Sockets.SocketException e) { //FDEBUG.Debug.LogMessage(this, 10, "Receive_Poll e=" + e.ToString()); if (reclen_total == 0) return -1; else return reclen_total; } if (reclen == 0) return reclen_total; byte[] buf = new byte[reclen]; try { reclen = sock.Receive(buf); } catch (System.Net.Sockets.SocketException e) { //FDEBUG.Debug.LogMessage(this, 10, "Receive_Poll e=" + e.ToString()); if (reclen_total == 0) return -1; else return reclen_total; } if (reclen > 0) { in_buffer.AddRange(buf); reclen_total += reclen; comm_time = DateTime.Now; } } } protected void Init() { if (first_poll) { comm_time = DateTime.Now; heartbeat_time = DateTime.Now; first_poll = false; } } public virtual int OnPoll() { int ret = 0; Init(); int reclen = Receive_Poll(); if (reclen < 0) { ret = -1; goto end; } else if (reclen == 0) { if ((DateTime.Now - comm_time) > Silent_Time)//长时间没收到东西 { //FDEBUG.Debug.LogMessage(this, 10, "ERROR 超时出错!"); ret = -2; goto end; } } else { int len=ParsePacket(this,in_buffer.ToArray()); if (len > 0) { in_buffer.RemoveRange(0, len); } } int sendlen = Send_Poll2(); if (sendlen < 0) { ret = -1; goto end; } end: if (ret != 0) { //连接断开 Enable = false; } return ret; } #region IFConn 成员 public event Action<TCPConn> ConnectEvent; protected bool isconnected = false; public virtual bool IsConnected { get { return isconnected; } set { if (isconnected != value) { isconnected = value; if (ConnectEvent != null) ConnectEvent(this); } } } protected bool enable = false; public bool Enable { get { return enable; } set { enable = value; if (enable == false) { Stop(); } } } protected virtual void Stop() { if (sock != null) sock.Close(); IsConnected = false; } #endregion #region IFConn 成员 public uint TranID { get; set; } #endregion } }