using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; using System.Management; using HPSocketCS.Extended; using System.Runtime.InteropServices; namespace HPNetwork.TCPNetworkServer { #region 在线用户列表 2017/07/03 /// <summary> /// 在线用户列表; /// </summary> public struct OnlineUser { public IntPtr ConnId; public string strBranchId; public DateTime dtQueryTask; public DateTime dtQueryNeedDownload; public DateTime dtQueryBranchDetail; } #endregion /// <summary> /// TCP网络通信服务端 /// </summary> public class TCP_NetworkServer { #region 在线用户列表 2017/07/03 /// <summary> /// 在线用户列表; /// </summary> private List<OnlineUser> onlineuserlist = new List<OnlineUser>(); /// <summary> /// 在线用户列表; /// </summary> public List<OnlineUser> OnlineUserList { get { return onlineuserlist; } set { onlineuserlist = value; } } public bool IsOnlineUserExists(string branchId) { bool bExists = false; foreach ( OnlineUser user in OnlineUserList ) { if (branchId == user.strBranchId) { bExists = true; break; } } return bExists; } public void AddOnlineUser(IntPtr connId, string branchId) { if (IsOnlineUserExists(branchId)) return; OnlineUser user = new OnlineUser { ConnId = connId, strBranchId = branchId, dtQueryTask = DateTime.Now, dtQueryNeedDownload = DateTime.Now, dtQueryBranchDetail = DateTime.Now }; OnlineUserList.Add(user); } public void RemoveOnlineUser(IntPtr connId) { foreach (OnlineUser user in OnlineUserList) { if (connId == user.ConnId) { onlineuserlist.Remove(user); break; } } } public void RemoveOnlineUser(string branchId) { foreach (OnlineUser user in OnlineUserList) { if (branchId == user.strBranchId) { onlineuserlist.Remove(user); break; } } } public bool IsQueryTaskTimeOut(IntPtr connId) { for (int i = 0; i < OnlineUserList.Count; i++ ) { OnlineUser user = OnlineUserList[i]; if (connId == user.ConnId) { TimeSpan tSpan = DateTime.Now - user.dtQueryTask; if (tSpan.TotalMilliseconds > 15000) { user.dtQueryTask = DateTime.Now; return true; } } } return false; } public bool IsQueryNeedDownloadTimeOut(IntPtr connId) { for (int i = 0; i < OnlineUserList.Count; i++) { OnlineUser user = OnlineUserList[i]; if (connId == user.ConnId) { TimeSpan tSpan = DateTime.Now - user.dtQueryNeedDownload; if (tSpan.TotalMilliseconds > 15000) { user.dtQueryNeedDownload = DateTime.Now; return true; } } } return false; } public bool IsQueryBranchDetailTimeOut(IntPtr connId) { for (int i = 0; i < OnlineUserList.Count; i++) { OnlineUser user = OnlineUserList[i]; if (connId == user.ConnId) { TimeSpan tSpan = DateTime.Now - user.dtQueryBranchDetail; if (tSpan.TotalMilliseconds > 15000) { user.dtQueryBranchDetail = DateTime.Now; return true; } } } return false; } #endregion public TCP_NetworkServer() { } public TCP_NetworkServer(HPSocketCS.Extended.CustomTraceListener _traceListenerLog) { this.TraceListenerLog = _traceListenerLog; } #region 网络程序处理代码 private AppState appState = AppState.Stoped; public HPSocketCS.TcpPackServer hp_Server = new HPSocketCS.TcpPackServer(); HPSocketCS.Extended.CustomTraceListener _TraceListenerLog = null; /// <summary> /// 服务器运行日志跟踪侦听器 /// </summary> public HPSocketCS.Extended.CustomTraceListener TraceListenerLog { get { return _TraceListenerLog; } set { _TraceListenerLog = value; } } /// <summary> /// 启动网络 /// </summary> /// <param name="ip"></param> /// <param name="port"></param> public void StartRun(string ip = "0.0.0.0", ushort port = 8500) { try { if (!this.isInitializesNetwork) { this.InitializesNetwork(); } ServerStartTimeStamp = "1492583059892";//DateTime.Now.ToString("yyyyMMddHHmmsss"); // 写在这个位置是上面可能会异常 SetAppState(AppState.Starting); hp_Server.IpAddress = ip; hp_Server.Port = port; // 启动服务 if (hp_Server.Start()) { SetAppState(AppState.Started); SystemFileLogs.WriteLogs("服务器网络启动成功 IP:" + ip + ":" + port.ToString(), this.TraceListenerLog); } else { SetAppState(AppState.Stoped); throw new Exception(string.Format("$绑定套接字失败(套接字绑定),可能是端口“" + port.ToString() + "”被占用 -> {0}({1})", hp_Server.ErrorMessage, hp_Server.ErrorCode)); } } catch (Exception ex) { SystemFileLogs.WriteLogs("服务器网络启动失败:" + ex.Message, this.TraceListenerLog); } } public void StopRun() { try { if (this.IsInitializesNetwork) { SetAppState(AppState.Stoping); // 停止服务 SystemFileLogs.WriteLogs("服务器网络停止服务", this.TraceListenerLog); if (hp_Server.Stop()) { SetAppState(AppState.Stoped); } else { SystemFileLogs.WriteLogs("服务器网络停止服务时出错:" + hp_Server.ErrorMessage + "(" + hp_Server.ErrorCode + ")", this.TraceListenerLog); } } } catch { } } bool isInitializesNetwork = false; /// <summary> /// 网络服务是否已初始化 /// </summary> public bool IsInitializesNetwork { get { return isInitializesNetwork; } set { isInitializesNetwork = value; } } /// <summary> /// 初始化网络 /// </summary> void InitializesNetwork() { try { // 设置服务器事件 hp_Server.OnPrepareListen += new HPSocketCS.TcpServerEvent.OnPrepareListenEventHandler(OnPrepareListen); hp_Server.OnAccept += new HPSocketCS.TcpServerEvent.OnAcceptEventHandler(OnAccept); hp_Server.OnSend += new HPSocketCS.TcpServerEvent.OnSendEventHandler(OnSend); hp_Server.OnReceive += new HPSocketCS.TcpServerEvent.OnReceiveEventHandler(OnReceive); hp_Server.OnClose += new HPSocketCS.TcpServerEvent.OnCloseEventHandler(OnClose); hp_Server.OnShutdown += new HPSocketCS.TcpServerEvent.OnShutdownEventHandler(OnShutdown); // 设置包头标识,与对端设置保证一致性 hp_Server.PackHeaderFlag = 0x1ff; // 设置最大封包大小 hp_Server.MaxPackSize = 0x2000 * 32; hp_Server.SocketBufferSize = 512 * 1024;//hp_Server.MaxPackSize; this.isInitializesNetwork = true; SystemFileLogs.WriteLogs("服务器初始化网络成功", this.TraceListenerLog); SetAppState(AppState.Stoped); } catch (Exception ex) { SetAppState(AppState.Error); SystemFileLogs.WriteLogs("服务器初始化网络时出错:" + ex.Message, this.TraceListenerLog); } } /// <summary> /// 准备监听了事件 /// </summary> /// <param name="soListen"></param> /// <returns></returns> HPSocketCS.HandleResult OnPrepareListen(IntPtr soListen) { // 监听事件到达了,一般没什么用吧? SystemFileLogs.WriteLogs("服务器已成功开始网络侦听...", this.TraceListenerLog); return HPSocketCS.HandleResult.Ok; } /// <summary> /// 连接到达事件 /// </summary> /// <param name="connId"></param> /// <param name="pClient"></param> /// <returns></returns> HPSocketCS.HandleResult OnAccept(IntPtr connId, IntPtr pClient) { // 客户进入了 // 获取客户端ip和端口 string ip = string.Empty; ushort port = 0; if (hp_Server.GetRemoteAddress(connId, ref ip, ref port)) { SystemFileLogs.WriteLogs("收接连接请求:" + ip + ":" + port.ToString(), this.TraceListenerLog); } else { SystemFileLogs.WriteLogs("获取某个连接的ip和端口时出错", this.TraceListenerLog); return HPSocketCS.HandleResult.Error; } // 设置附加数据 HPSocketCS.Extended.ClientInfo ci = new HPSocketCS.Extended.ClientInfo(); ci.ConnId = connId; ci.IpAddress = ip; ci.Port = port; if (hp_Server.SetConnectionExtra(connId, ci) == false) { SystemFileLogs.WriteLogs("设置连接的附加数据失败,IP地址为 " + ip + ":" + port.ToString(), this.TraceListenerLog); return HPSocketCS.HandleResult.Error; } return HPSocketCS.HandleResult.Ok; } /// <summary> /// 数据包发送事件 /// </summary> /// <param name="connId"></param> /// <param name="bytes"></param> /// <returns></returns> HPSocketCS.HandleResult OnSend(IntPtr connId, byte[] bytes) { // 服务器发数据了 return HPSocketCS.HandleResult.Ok; } /// <summary> /// 数据到达 /// </summary> /// <param name="connId"></param> /// <param name="bytes"></param> /// <returns></returns> HPSocketCS.HandleResult OnReceive(IntPtr connId, byte[] bytes) { // 数据到达了 try { bool retProcessed = true;//处理情况 //收到的数据 byte[] receiveBytes = new byte[0]; TcpHeadInfo header = hp_Server.BytesToStruct<TcpHeadInfo>(bytes); DataType dType = (DataType)header.MsgDataType; int headSize = Marshal.SizeOf(header); TcpTailInfo tail = new TcpTailInfo(); if (header.IsTail) { //有附加尾数据时 int tailSize = Marshal.SizeOf(tail); byte[] tailBytes = new byte[tailSize]; Array.ConstrainedCopy(bytes, bytes.Length - tailSize, tailBytes, 0, tailBytes.Length); tail = hp_Server.BytesToStruct<TcpTailInfo>(tailBytes); receiveBytes = new byte[bytes.Length - headSize - tailSize]; Array.ConstrainedCopy(bytes, headSize, receiveBytes, 0, receiveBytes.Length); tailBytes = null; } else { // 因为没有附加尾数据,所以大小可以用length - objSize receiveBytes = new byte[bytes.Length - headSize]; Array.ConstrainedCopy(bytes, headSize, receiveBytes, 0, receiveBytes.Length); } bytes = null; //接收到的客户端发送来的数据 byte[] recbytes = null; try { if (header.TransportStart && header.TransportEnd) { recbytes = receiveBytes; receiveBytes = null; } else { ReceiveData rData = hp_Server.SCommonLibrary.GetReceiveData(header); if (rData == null) { rData = new ReceiveData(); hp_Server.SCommonLibrary.AddReceiveData(rData); } rData.ReceiveRemoteClientInfo = header; rData.ReceiveDataMstream.Write(receiveBytes, 0, receiveBytes.Length); if (header.TransportEnd) { rData.ReceiveDataMstream.Position = 0; //recbytes = rData.ReceiveDataMstream.ToArray(); recbytes = new byte[rData.ReceiveDataMstream.Length]; rData.ReceiveDataMstream.Read(recbytes, 0, recbytes.Length); hp_Server.SCommonLibrary.RemoveReceiveDataData(rData); } } if (recbytes != null) { recbytes = HPSocketCS.Extended.DataSetSerializerDeserialize.DataDecompressRetBytes(recbytes); switch (dType) { case DataType.File: FileRequestType RequestType = (FileRequestType)tail.RequestType; if (this.EventFileDataRequest != null) { this.EventFileDataRequest(hp_Server, header, tail, connId, recbytes); } switch (RequestType) { case FileRequestType.Upload: //接收文件 retProcessed = hp_Server.ReceiveFileToServerRootDirectory(tail, recbytes); break; case FileRequestType.Download: //发送文件 retProcessed = hp_Server.SenFileToClient(header, tail, connId); break; } break; case DataType.SQLHelper: case DataType.Serialization: if (this.EventSerializationDataRequest != null) { this.EventSerializationDataRequest(hp_Server, header, connId, recbytes); } break; case DataType.List: break; case DataType.Array: break; case DataType.None: break; } } } finally { try { System.Array.Clear(recbytes, 0, recbytes.Length); } catch { } recbytes = null; } if (retProcessed) { return HPSocketCS.HandleResult.Ok; } else { //return HandleResult.Error; return HPSocketCS.HandleResult.Ignore; } } catch (Exception ex) { SystemFileLogs.WriteLogs("接收数据时出错:" + ex.Message, this.TraceListenerLog); return HPSocketCS.HandleResult.Ignore; } finally { System.GC.Collect(); } } /// <summary> /// 连接关闭事件 /// </summary> /// <param name="connId"></param> /// <param name="enOperation"></param> /// <param name="errorCode"></param> /// <returns></returns> HPSocketCS.HandleResult OnClose(IntPtr connId, HPSocketCS.SocketOperation enOperation, int errorCode) { // 移除在线用户; RemoveOnlineUser(connId); if (errorCode == 0) { HPSocketCS.Extended.ClientInfo cInfo = hp_Server.GetClientInfo(connId); if (cInfo != null) { SystemFileLogs.WriteLogs(String.Format("ID为{0}的连接已关闭,IP:{1}:{2}", connId, cInfo.IpAddress, cInfo.Port), this.TraceListenerLog); } else { SystemFileLogs.WriteLogs(String.Format("ID为{0}的连接已关闭", connId), this.TraceListenerLog); } } else if (enOperation == HPSocketCS.SocketOperation.Close) { SystemFileLogs.WriteLogs(String.Format("客户端已关闭连接 > [{0},OnError] -> OP:{1},CODE:{2}", connId, enOperation, errorCode), this.TraceListenerLog); } else { SystemFileLogs.WriteLogs(String.Format("连接出错 > [{0},OnError] -> OP:{1},CODE:{2}", connId, enOperation, errorCode), this.TraceListenerLog); // return HPSocketSdk.HandleResult.Ok; return HPSocketCS.HandleResult.Error; } //hp_Server.SCommonLibrary.ClearInvalidConnectionResource(connId); //if (hp_Server.SetConnectionExtra(connId, null) == false) //{ // SystemFileLogs.WriteLogs("清除连接的附加数据失败:" + errorCode, this.TraceListenerLog); //} return HPSocketCS.HandleResult.Ok; } /// <summary> /// 服务器关闭事件 /// </summary> /// <returns></returns> HPSocketCS.HandleResult OnShutdown() { // 服务关闭了 hp_Server.SCommonLibrary.ClearAllInvalidResource(); return HPSocketCS.HandleResult.Ok; } /// <summary> /// 设置程序状态 /// </summary> /// <param name="state"></param> void SetAppState(AppState state) { appState = state; } static string _ServerStartTimeStamp = ""; /// <summary> /// 服务器启动时间标识 /// </summary> public static string ServerStartTimeStamp { get { return TCP_NetworkServer._ServerStartTimeStamp; } set { TCP_NetworkServer._ServerStartTimeStamp = value; } } /// <summary> /// 申明委托 /// </summary> /// <param name="e"></param> /// <returns></returns> // public delegate void EventLockVerifiedHandler(EventLockVerified e); /// <summary> /// EventClientLockVerified事件 /// </summary> // public event EventLockVerifiedHandler EventClientLockVerified; #endregion #region 客户端请求处理事件 /// <summary> /// 申明客户端请求处理事件委托 /// </summary> /// <param name="hp_Server"></param> /// <param name="header"></param> /// <param name="connId"></param> /// <param name="bytes"></param> public delegate void EventSerializationDataRequestHandler(HPSocketCS.TcpPackServer hp_Server, TcpHeadInfo header, IntPtr connId, byte[] bytes); /// <summary> /// 申明客户端请求处理事件 /// </summary> public event EventSerializationDataRequestHandler EventSerializationDataRequest; /// <summary> /// 申明客户端请求文件传输处理事件委托 /// </summary> /// <param name="hp_Server"></param> /// <param name="header"></param> /// <param name="connId"></param> /// <param name="bytes"></param> public delegate void EventFileDataRequestHandler(HPSocketCS.TcpPackServer hp_Server, TcpHeadInfo header, TcpTailInfo tail, IntPtr connId, byte[] bytes); /// <summary> /// 申明客户端请求文件传输处理事件 /// </summary> public event EventFileDataRequestHandler EventFileDataRequest; #endregion } /// <summary> /// EventLockVerified 客户端连接事件对象 /// </summary> public class EventLockVerified : EventArgs { public EventLockVerified() { } HPSocketCS.Extended.ClientInfo _CInfo; /// <summary> /// 客户端信息 /// </summary> public HPSocketCS.Extended.ClientInfo CInfo { get { return _CInfo; } set { _CInfo = value; } } } }