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 LYFZ.Network.TCPNetworkServer { /// /// TCP网络通信服务端 /// public class TCP_NetworkServer { 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; /// /// 服务器运行日志跟踪侦听器 /// public HPSocketCS.Extended.CustomTraceListener TraceListenerLog { get { return _TraceListenerLog; } set { _TraceListenerLog = value; } } /// /// 启动网络 /// /// /// 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; /// /// 网络服务是否已初始化 /// public bool IsInitializesNetwork { get { return isInitializesNetwork; } set { isInitializesNetwork = value; } } /// /// 初始化网络 /// 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); } } /// /// 准备监听了事件 /// /// /// HPSocketCS.HandleResult OnPrepareListen(IntPtr soListen) { // 监听事件到达了,一般没什么用吧? SystemFileLogs.WriteLogs("服务器已成功开始网络侦听...", this.TraceListenerLog); return HPSocketCS.HandleResult.Ok; } /// /// 连接到达事件 /// /// /// /// 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; } /// /// 数据包发送事件 /// /// /// /// HPSocketCS.HandleResult OnSend(IntPtr connId, byte[] bytes) { // 服务器发数据了 return HPSocketCS.HandleResult.Ok; } /// /// 数据到达 /// /// /// /// HPSocketCS.HandleResult OnReceive(IntPtr connId, byte[] bytes) { // 数据到达了 try { bool retProcessed = true;//处理情况 //收到的数据 byte[] receiveBytes = new byte[0]; TcpHeadInfo header = hp_Server.BytesToStruct(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(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.Text: retProcessed = this.DataTypeTextProcessed(header, connId, recbytes); break; 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 (hp_Server.Send(connId, bytes, bytes.Length)) { return HPSocketCS.HandleResult.Ok; }*/ 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(); } } /// /// 连接关闭事件 /// /// /// /// /// HPSocketCS.HandleResult OnClose(IntPtr connId, HPSocketCS.SocketOperation enOperation, int errorCode) { 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); } TCPNetworkServer.TCP_NetworkServer.AddOrSetClientList(new TCP_ClientConnectInfo(connId.ToInt32(), false)); ClientRequestObject requestObject = new ClientRequestObject(); try { requestObject.ConnID = connId.ToInt32(); TCP_RemoteDataHandlerPassiveMode.RemoveGenerateThumbnailsRequest(requestObject); } catch { } finally { requestObject = null; } return HPSocketCS.HandleResult.Ok; } /// /// 服务器关闭事件 /// /// HPSocketCS.HandleResult OnShutdown() { // 服务关闭了 hp_Server.SCommonLibrary.ClearAllInvalidResource(); return HPSocketCS.HandleResult.Ok; } /// /// 设置程序状态 /// /// void SetAppState(AppState state) { appState = state; } /// /// 服务器端接收客户端发送的文本数据请求并处理返回结果 /// /// 协议头 /// 连接ID /// 收到的数据 public bool DataTypeTextProcessed(TcpHeadInfo header, IntPtr connId, byte[] bytes) { bool ret = false; TCP_RemoteDataHandlerPassiveMode RDHandler = new TCP_RemoteDataHandlerPassiveMode(); TransferRequestCommand Command = (TransferRequestCommand)Convert.ToInt32(header.RequestCommand); try { string ReceiveInfo = Encoding.UTF8.GetString(bytes, 0, bytes.Length); TCP_ProtocolHelperXML pXml = new TCP_ProtocolHelperXML(ReceiveInfo); TCP_FileProtocol returnProtocol = new TCP_FileProtocol(); TCP_FileProtocol recprotocol = pXml.GetProtocol(); TCP_ClientConnectInfo cInfo = new TCP_ClientConnectInfo(connId.ToInt32(), header); recprotocol.ClientInfo = cInfo.ToString(); try { switch (Command) { case TransferRequestCommand.Message: returnProtocol = new TCP_FileProtocol("服务器已接收到:" + recprotocol.Content + "..."); break; case TransferRequestCommand.DeleteFile: returnProtocol = RDHandler.DeleteFile(recprotocol); break; case TransferRequestCommand.GeTFileList: returnProtocol = RDHandler.GeTFileList(recprotocol); break; case TransferRequestCommand.GetDirectoryList: returnProtocol = RDHandler.GetDirectoryList(recprotocol); break; case TransferRequestCommand.DeleteDirectory: returnProtocol = RDHandler.DeleteDirectory(recprotocol); break; case TransferRequestCommand.GetFileInfo: returnProtocol = RDHandler.GetFileInfo(recprotocol); break; case TransferRequestCommand.GetBackupRecords: returnProtocol = RDHandler.GetBackupRecords(recprotocol); break; case TransferRequestCommand.GetMainShopBackupRecords: returnProtocol = RDHandler.GetMainShopBackupRecords(recprotocol); break; default: returnProtocol = new TCP_FileProtocol("非法指令,服务器拒绝执行..."); break; } } catch (Exception ex) { returnProtocol = new TCP_FileProtocol("网络请求处理失败,原因:" + ex.Message); } byte[] sendBytes = null; if (returnProtocol.InfoType == EnumerateLibrary.InformationType.Data) { sendBytes = returnProtocol.DataArray; } else { sendBytes = Encoding.UTF8.GetBytes(returnProtocol.ToString()); } ret = hp_Server.AutoUnpackingAndSend(connId, sendBytes, header.TransportID, DataType.Text, Command); RDHandler = null; System.GC.Collect(); } catch (Exception ex) { try { SystemFileLogs.WriteLogs("服务器处理客户端请求时出错:" + ex.Message, this.TraceListenerLog); byte[] sendBytes = Encoding.UTF8.GetBytes(new TCP_FileProtocol("服务器处理客户端请求时出错:" + ex.Message).ToString()); ret = hp_Server.AutoUnpackingAndSend(connId, sendBytes, header.TransportID, DataType.Text, Command); RDHandler = null; } catch { } } return ret; } static List _ClientConnList = new List(); /// /// 获取客户端连接集合 用于管理客户端成功连接座席数 /// public static List ClientConnList { get { return _ClientConnList; } } /// /// 添加和设置客户端连接 /// /// /// 是否为刷新客户端连接,刷新客户端时不做客户端添加(一搬用于已满座席时) public static void AddOrSetClientList(TCP_ClientConnectInfo connInfo, bool isRefresh = false) { if (connInfo.HostIdentity.Trim().ToLower() == "ServerHosts".ToLower()) { return; } lock (ClientConnList) { bool isConnInfo = false; connInfo.ConnectionTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); foreach (TCP_ClientConnectInfo cinfo in ClientConnList) { try { if (cinfo.ConnId == connInfo.ConnId) { cinfo.ConnStatus = connInfo.ConnStatus; cinfo.ConnectionTime = connInfo.ConnectionTime; } } catch { } try { if (connInfo.ConnStatus && cinfo.HostIdentity.Trim().Length > 0) { if (cinfo.HostIdentity.Trim().ToLower() == connInfo.HostIdentity.Trim().ToLower()) { cinfo.ConnId = connInfo.ConnId; cinfo.ConnStatus = connInfo.ConnStatus; cinfo.ConnectionTime = connInfo.ConnectionTime; cinfo.IP = connInfo.IP; cinfo.Port = connInfo.Port; cinfo.LoginUsername = connInfo.LoginUsername; isConnInfo = true; break; } } } catch { } } if (!isConnInfo && connInfo.ConnStatus && !isRefresh) { ClientConnList.Add(connInfo); } } } static string _ServerStartTimeStamp = ""; /// /// 服务器启动时间标识 /// public static string ServerStartTimeStamp { get { return TCP_NetworkServer._ServerStartTimeStamp; } set { TCP_NetworkServer._ServerStartTimeStamp = value; } } /// /// 申明委托 /// /// /// // public delegate void EventLockVerifiedHandler(EventLockVerified e); /// /// EventClientLockVerified事件 /// // public event EventLockVerifiedHandler EventClientLockVerified; #endregion #region 客户端请求处理事件 /// /// 申明客户端请求处理事件委托 /// /// /// /// /// public delegate void EventSerializationDataRequestHandler(HPSocketCS.TcpPackServer hp_Server, TcpHeadInfo header, IntPtr connId, byte[] bytes); /// /// 申明客户端请求处理事件 /// public event EventSerializationDataRequestHandler EventSerializationDataRequest; /// /// 申明客户端请求文件传输处理事件委托 /// /// /// /// /// public delegate void EventFileDataRequestHandler(HPSocketCS.TcpPackServer hp_Server, TcpHeadInfo header, TcpTailInfo tail, IntPtr connId, byte[] bytes); /// /// 申明客户端请求文件传输处理事件 /// public event EventFileDataRequestHandler EventFileDataRequest; #endregion } /// /// EventLockVerified 客户端连接事件对象 /// public class EventLockVerified : EventArgs { public EventLockVerified() { } HPSocketCS.Extended.ClientInfo _CInfo; /// /// 客户端信息 /// public HPSocketCS.Extended.ClientInfo CInfo { get { return _CInfo; } set { _CInfo = value; } } } }