/// <summary> /// 客户端向服务器进行请求,请求字符串数据,忽略了自定义消息反馈 /// </summary> /// <param name="customer">用户的指令头</param> /// <param name="send">发送数据</param> /// <returns>带返回消息的结果对象</returns> public OperateResult <string> ReadFromServer(NetHandle customer, string send) { var read = ReadFromServerBase(HslProtocol.CommandBytes(customer, Token, send)); if (!read.IsSuccess) { return(OperateResult.CreateFailedResult <string>(read)); } return(OperateResult.CreateSuccessResult(Encoding.Unicode.GetString(read.Content))); }
/// <summary> /// 客户端向服务器进行请求,请求字符串数组,忽略了自定义消息反馈 /// </summary> /// <param name="customer">用户的指令头</param> /// <param name="send">发送数据</param> /// <returns>带返回消息的结果对象</returns> public OperateResult <string[]> ReadFromServer(NetHandle customer, string[] send) { var read = ReadFromServerBase(HslProtocol.CommandBytes(customer, Token, send)); if (!read.IsSuccess) { return(OperateResult.CreateFailedResult <string[]>(read)); } return(OperateResult.CreateSuccessResult(HslProtocol.UnPackStringArrayFromByte(read.Content))); }
/// <summary> /// 关闭该客户端引擎 /// </summary> public void ClientClose( ) { IsQuie = true; if (IsClientStart) { SendBytes(stateone, HslProtocol.CommandBytes(HslProtocol.ProtocolClientQuit, 0, Token, null)); } thread_heart_check?.Abort( ); IsClientStart = false; Thread.Sleep(5); LoginSuccess = null; LoginFailed = null; MessageAlerts = null; AcceptByte = null; AcceptString = null; stateone.WorkSocket?.Close( ); LogNet?.WriteDebug(ToString(), "Client Close."); }
/// <summary> /// 需要发送的底层数据 /// </summary> /// <param name="headcode">数据的指令头</param> /// <param name="customer">用户的指令头</param> /// <param name="send">需要发送的底层数据</param> /// <returns>带返回消息的结果对象</returns> private OperateResult <byte[]> ReadFromServerBase(int headcode, int customer, byte[] send) { var read = ReadFromCoreServer(HslProtocol.CommandBytes(headcode, customer, Token, send)); if (!read.IsSuccess) { return(read); } byte[] headBytes = new byte[HslProtocol.HeadByteLength]; byte[] contentBytes = new byte[read.Content.Length - HslProtocol.HeadByteLength]; Array.Copy(read.Content, 0, headBytes, 0, HslProtocol.HeadByteLength); if (contentBytes.Length > 0) { Array.Copy(read.Content, HslProtocol.HeadByteLength, contentBytes, 0, read.Content.Length - HslProtocol.HeadByteLength); } contentBytes = HslProtocol.CommandAnalysis(headBytes, contentBytes); return(OperateResult.CreateSuccessResult(contentBytes)); }
/// <summary> /// 需要发送的底层数据 /// </summary> /// <param name="send">需要发送的底层数据</param> /// <returns>带返回消息的结果对象</returns> private OperateResult <byte[]> ReadFromServerBase(byte[] send) { // 核心数据交互 var read = ReadFromCoreServer(send); if (!read.IsSuccess) { return(read); } // 提炼数据信息 byte[] headBytes = new byte[HslProtocol.HeadByteLength]; byte[] contentBytes = new byte[read.Content.Length - HslProtocol.HeadByteLength]; Array.Copy(read.Content, 0, headBytes, 0, HslProtocol.HeadByteLength); if (contentBytes.Length > 0) { Array.Copy(read.Content, HslProtocol.HeadByteLength, contentBytes, 0, read.Content.Length - HslProtocol.HeadByteLength); } contentBytes = HslProtocol.CommandAnalysis(headBytes, contentBytes); return(OperateResult.CreateSuccessResult(contentBytes)); }
/// <summary> /// 服务器端用于数据发送文本的方法 /// </summary> /// <param name="session">数据发送对象</param> /// <param name="customer">用户自定义的数据对象,如不需要,赋值为0</param> /// <param name="str">发送的文本</param> public void Send(AppSession session, NetHandle customer, string str) { SendBytes(session, HslProtocol.CommandBytes(customer, Token, str)); }
private void AsyncCallback(IAsyncResult ar) { if (ar.AsyncState is AppSession session) { try { int received = session.WorkSocket.EndReceiveFrom(ar, ref session.UdpEndPoint); // 释放连接关联 session.WorkSocket = null; // 马上开始重新接收,提供性能保障 RefreshReceive( ); // 处理数据 if (received >= HslProtocol.HeadByteLength) { // 检测令牌 if (CheckRemoteToken(session.BytesContent)) { session.IpEndPoint = (IPEndPoint)session.UdpEndPoint; int contentLength = BitConverter.ToInt32(session.BytesContent, HslProtocol.HeadByteLength - 4); if (contentLength == received - HslProtocol.HeadByteLength) { byte[] head = new byte[HslProtocol.HeadByteLength]; byte[] content = new byte[contentLength]; Array.Copy(session.BytesContent, 0, head, 0, HslProtocol.HeadByteLength); if (contentLength > 0) { Array.Copy(session.BytesContent, 32, content, 0, contentLength); } // 解析内容 content = HslProtocol.CommandAnalysis(head, content); int protocol = BitConverter.ToInt32(head, 0); int customer = BitConverter.ToInt32(head, 4); // 丢给数据中心处理 DataProcessingCenter(session, protocol, customer, content); } else { // 否则记录到日志 LogNet?.WriteWarn(ToString(), $"Should Rece:{(BitConverter.ToInt32( session.BytesContent, 4 ) + 8)} Actual:{received}"); } } else { LogNet?.WriteWarn(ToString( ), StringResources.Language.TokenCheckFailed); } } else { LogNet?.WriteWarn(ToString( ), $"Receive error, Actual:{received}"); } } catch (ObjectDisposedException) { //主程序退出的时候触发 } catch (Exception ex) { LogNet?.WriteException(ToString( ), StringResources.Language.SocketEndReceiveException, ex); //重新接收,此处已经排除掉了对象释放的异常 RefreshReceive( ); } finally { //state = null; } } }
/// <summary> /// 向指定的通信对象发送字节数据 /// </summary> /// <param name="session">连接对象</param> /// <param name="customer">用户的指令头</param> /// <param name="bytes">实际的数据</param> public void SendMessage(AppSession session, int customer, byte[] bytes) { SendBytesAsync(session, HslProtocol.CommandBytes(customer, Token, bytes)); }
/// <summary> /// 向指定的通信对象发送字符串数据 /// </summary> /// <param name="session">通信对象</param> /// <param name="customer">用户的指令头</param> /// <param name="str">实际发送的字符串数据</param> public void SendMessage(AppSession session, int customer, string str) { SendBytesAsync(session, HslProtocol.CommandBytes(customer, Token, str)); }
/// <summary> /// [自校验] 接收一条完整的同步数据,包含头子节和内容字节,基础的数据,如果结果异常,则结束通讯 /// </summary> /// <param name="socket">套接字</param> /// <param name="timeout">超时时间设置,如果为负数,则不检查超时</param> /// <returns></returns> /// <exception cref="ArgumentNullException">result</exception> protected OperateResult <byte[], byte[]> ReceiveAndCheckBytes(Socket socket, int timeout) { // 30秒超时接收验证 HslTimeOut hslTimeOut = new HslTimeOut( ) { DelayTime = timeout, IsSuccessful = false, StartTime = DateTime.Now, WorkSocket = socket, }; if (timeout > 0) { ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), hslTimeOut); } // 接收头指令 OperateResult <byte[]> headResult = Receive(socket, HslProtocol.HeadByteLength); if (!headResult.IsSuccess) { hslTimeOut.IsSuccessful = true; return(new OperateResult <byte[], byte[]>( ) { Message = headResult.Message }); } hslTimeOut.IsSuccessful = true; // 检查令牌 if (!CheckRemoteToken(headResult.Content)) { socket?.Close( ); return(new OperateResult <byte[], byte[]>( ) { Message = StringResources.TokenCheckFailed }); } int contentLength = BitConverter.ToInt32(headResult.Content, HslProtocol.HeadByteLength - 4); // 接收内容 OperateResult <byte[]> contentResult = Receive(socket, contentLength); if (!contentResult.IsSuccess) { return(new OperateResult <byte[], byte[]>( ) { Message = contentResult.Message }); } // 返回成功信息 OperateResult checkResult = SendLong(socket, HslProtocol.HeadByteLength + contentLength); if (!checkResult.IsSuccess) { return(new OperateResult <byte[], byte[]>( ) { Message = checkResult.Message }); } byte[] head = headResult.Content; byte[] content = contentResult.Content; content = HslProtocol.CommandAnalysis(head, content); return(OperateResult.CreateSuccessResult(head, content)); }
/// <summary> /// 客户端向服务器进行请求,请求字节数据 /// </summary> /// <param name="customer">用户的指令头</param> /// <param name="send">发送的字节内容</param> /// <returns>带返回消息的结果对象</returns> public OperateResult <byte[]> ReadFromServer(NetHandle customer, byte[] send) { return(ReadFromServerBase(HslProtocol.CommandBytes(customer, Token, send))); }
/// <summary> /// [自校验] 从网络中接收一个字符串数组,如果结果异常,则结束通讯 /// </summary> /// <param name="socket">套接字</param> /// <returns>包含是否成功的结果对象</returns> protected OperateResult <int, string[]> ReceiveStringArrayContentFromSocket(Socket socket) { OperateResult <byte[], byte[]> receive = ReceiveAndCheckBytes(socket, 10000); if (!receive.IsSuccess) { return(OperateResult.CreateFailedResult <int, string[]>(receive)); } // 检查是否是字符串信息 if (BitConverter.ToInt32(receive.Content1, 0) != HslProtocol.ProtocolUserStringArray) { LogNet?.WriteError(ToString( ), StringResources.Language.CommandHeadCodeCheckFailed); socket?.Close( ); return(new OperateResult <int, string[]>(StringResources.Language.CommandHeadCodeCheckFailed)); } if (receive.Content2 == null) { receive.Content2 = new byte[4]; } return(OperateResult.CreateSuccessResult(BitConverter.ToInt32(receive.Content1, 4), HslProtocol.UnPackStringArrayFromByte(receive.Content2))); }
/// <summary> /// [自校验] 直接发送字符串数组并确认对方接收完成数据,如果结果异常,则结束通讯 /// </summary> /// <param name="socket">网络套接字</param> /// <param name="customer">用户指令</param> /// <param name="name">用户名</param> /// <param name="pwd">密码</param> /// <returns>是否发送成功</returns> protected OperateResult SendAccountAndCheckReceive(Socket socket, int customer, string name, string pwd) { return(SendBaseAndCheckReceive(socket, HslProtocol.ProtocolAccountLogin, customer, HslProtocol.PackStringArrayToByte(new string[] { name, pwd }))); }
/// <summary> /// [自校验] 直接发送字符串数组并确认对方接收完成数据,如果结果异常,则结束通讯 /// </summary> /// <param name="socket">网络套接字</param> /// <param name="customer">用户指令</param> /// <param name="sends">发送的字符串数组</param> /// <returns>是否发送成功</returns> protected OperateResult SendStringAndCheckReceive(Socket socket, int customer, string[] sends) { return(SendBaseAndCheckReceive(socket, HslProtocol.ProtocolUserStringArray, customer, HslProtocol.PackStringArrayToByte(sends))); }
private void ThreadLogin( ) { lock (lock_connecting) { if (IsClientConnecting) { return; } IsClientConnecting = true; } if (ConnectFailedCount == 0) { MessageAlerts?.Invoke("正在连接服务器..."); } else { int count = 10; while (count > 0) { if (IsQuie) { return; } MessageAlerts?.Invoke("连接断开,等待" + count-- + "秒后重新连接"); Thread.Sleep(1000); } MessageAlerts?.Invoke("正在尝试第" + ConnectFailedCount + "次连接服务器..."); } stateone.HeartTime = DateTime.Now; LogNet?.WriteDebug(ToString( ), "Begin Connect Server, Times: " + ConnectFailedCount); OperateResult <Socket> connectResult = CreateSocketAndConnect(EndPointServer, 10000); if (!connectResult.IsSuccess) { ConnectFailedCount++; IsClientConnecting = false; LoginFailed?.Invoke(ConnectFailedCount); LogNet?.WriteDebug(ToString( ), "Connected Failed, Times: " + ConnectFailedCount); // 连接失败,重新连接服务器 ReconnectServer( ); return; } // 连接成功,发送数据信息 OperateResult sendResult = SendStringAndCheckReceive(connectResult.Content, 1, ClientAlias); if (!sendResult.IsSuccess) { ConnectFailedCount++; IsClientConnecting = false; LogNet?.WriteDebug(ToString( ), "Login Server Failed, Times: " + ConnectFailedCount); LoginFailed?.Invoke(ConnectFailedCount); // 连接失败,重新连接服务器 ReconnectServer( ); return; } // 登录成功 ConnectFailedCount = 0; stateone.IpEndPoint = (IPEndPoint)connectResult.Content.RemoteEndPoint; stateone.LoginAlias = ClientAlias; stateone.WorkSocket = connectResult.Content; stateone.WorkSocket.BeginReceive(stateone.BytesHead, stateone.AlreadyReceivedHead, stateone.BytesHead.Length - stateone.AlreadyReceivedHead, SocketFlags.None, new AsyncCallback(HeadBytesReceiveCallback), stateone); // 发送一条验证消息 // SendBytes(stateone, CommunicationCode.CommandBytes(CommunicationCode.Hsl_Protocol_Check_Secends)); byte[] bytesTemp = new byte[16]; BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(bytesTemp, 0); SendBytes(stateone, HslProtocol.CommandBytes(HslProtocol.ProtocolCheckSecends, 0, Token, bytesTemp)); stateone.HeartTime = DateTime.Now; IsClientStart = true; LoginSuccess?.Invoke( ); LogNet?.WriteDebug(ToString( ), "Login Server Success, Times: " + ConnectFailedCount); IsClientConnecting = false; Thread.Sleep(1000); }
/// <summary> /// 服务器端用于发送字节的方法 /// </summary> /// <param name="session">数据发送对象</param> /// <param name="customer">用户自定义的数据对象,如不需要,赋值为0</param> /// <param name="bytes">实际发送的数据</param> public void Send(AppSession session, NetHandle customer, byte[] bytes) { SendBytes(session, HslProtocol.CommandBytes(customer, Token, bytes)); }
/// <summary> /// 发送字符串数据到服务器 /// </summary> /// <param name="customer">用户自定义的标记数据</param> /// <param name="data">字符串数据</param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="SocketException"></exception> /// <exception cref="ObjectDisposedException"></exception> public void SendMessage(NetHandle customer, string data) { CoreSocket.SendTo(HslProtocol.CommandBytes(customer, Token, data), ServerEndPoint); }
/// <summary> /// [自校验] 发送字节数据并确认对方接收完成数据,如果结果异常,则结束通讯 /// </summary> /// <param name="socket">网络套接字</param> /// <param name="headcode">头指令</param> /// <param name="customer">用户指令</param> /// <param name="send">发送的数据</param> /// <returns>是否发送成功</returns> protected OperateResult SendBaseAndCheckReceive(Socket socket, int headcode, int customer, byte[] send) { // 数据处理 send = HslProtocol.CommandBytes(headcode, customer, Token, send); return(Send(socket, send)); }