/// <summary> /// 当接收到了新的请求的时候执行的操作 /// </summary> /// <param name="obj">异步对象</param> protected override void ThreadPoolLogin(object obj) { // 为了提高系统的响应能力,采用异步来实现,即时有数万台设备接入也能应付 if (obj is Socket socket) { System.Net.IPEndPoint endPoint = (System.Net.IPEndPoint)socket.RemoteEndPoint; string ipAddress = endPoint.Address.ToString( ); if (IsTrustedClientsOnly) { // 检查受信任的情况 if (!CheckIpAddressTrusted(ipAddress)) { // 客户端不被信任,退出 LogNet?.WriteDebug(ToString( ), string.Format(StringResources.Language.ClientDisableLogin, endPoint)); socket.Close( ); return; } } LogNet?.WriteDebug(ToString( ), string.Format(StringResources.Language.ClientOnlineInfo, endPoint)); ThreadPoolLoginAfterClientCheck(socket, endPoint); } }
private void SimplifyServer_ReceiveStringEvent(AppSession session, NetHandle handle, string data) { if (handle == 0) { // 请求配置文件 simplifyServer.SendMessage(session, handle, xElementSettings != null ? xElementSettings.ToString() : string.Empty); } else if (handle == 1) { // 请求设备的所有数据 var nodePath = data.Split('\\', ':', '-', '.', '_', '/'); var response = string.Empty; for (var i = 0; i < deviceCores.Count; i++) { if (deviceCores[i].IsCurrentDevice(nodePath)) { response = deviceCores[i].GetValueByName(nodePath); break; } } LogNet?.WriteDebug("请求设备信息:" + data); simplifyServer.SendMessage(session, handle, response); } else { simplifyServer.SendMessage(session, handle, data); } }
/// <summary> /// 当客户端登录后,进行Ip信息的过滤,然后触发本方法,也就是说之后的客户端需要 /// </summary> /// <param name="socket">网络套接字</param> /// <param name="endPoint">终端节点</param> protected override void ThreadPoolLoginAfterClientCheck(Socket socket, System.Net.IPEndPoint endPoint) { // 接收注册包 DDPMessage dDPMessage = new DDPMessage(); OperateResult<byte[]> read = ReceiveByMessage(socket, int.MaxValue, dDPMessage);//5000 时间延长 if (!read.IsSuccess) return; string str = SoftBasic.ByteToSegmentation(read.Content); //OperateResult send = Send(socket, SoftBasic.HexStringToBytes("")); //if (!send.IsSuccess) return; // 开始接收数据信息 AppSession appSession = new AppSession(); appSession.IpEndPoint = endPoint; appSession.WorkSocket = socket; try { socket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(SocketAsyncCallBack), appSession); AddClient(appSession); } catch { socket.Close(); LogNet?.WriteDebug(ToString(), string.Format(StringResources.Language.ClientOfflineInfo, endPoint)); } }
/// <summary> /// 切换短连接模式到长连接模式,后面的每次请求都共享一个通道 /// </summary> /// <returns>返回连接结果,如果失败的话(也即IsSuccess为False),包含失败信息</returns> /// <example> /// 简单的连接示例,调用该方法后,连接设备,创建一个长连接的对象,后续的读写操作均公用一个连接对象。 /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Core\NetworkDoubleBase.cs" region="Connect1" title="连接设备" /> /// 如果想知道是否连接成功,请参照下面的代码。 /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Core\NetworkDoubleBase.cs" region="Connect2" title="判断连接结果" /> /// </example> public OperateResult ConnectServer( ) { isPersistentConn = true; OperateResult result = new OperateResult( ); // 重新连接之前,先将旧的数据进行清空 CoreSocket?.Close( ); OperateResult <Socket> rSocket = CreateSocketAndInitialication( ); if (!rSocket.IsSuccess) { IsSocketError = true; // 创建失败 rSocket.Content = null; result.Message = rSocket.Message; } else { CoreSocket = rSocket.Content; // 创建成功 result.IsSuccess = true; LogNet?.WriteDebug(ToString( ), StringResources.NetEngineStart); } return(result); }
/// <summary> /// 数据处理中心 /// </summary> /// <param name="receive"></param> /// <param name="protocol"></param> /// <param name="customer"></param> /// <param name="content"></param> internal override void DataProcessingCenter(AsyncStateOne receive, int protocol, int customer, byte[] content) { if (protocol == HslCommunicationCode.Hsl_Protocol_Check_Secends) { BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(content, 8); SendBytes(receive, NetSupport.CommandBytes(HslCommunicationCode.Hsl_Protocol_Check_Secends, customer, KeyToken, content)); receive.HeartTime = DateTime.Now; } else if (protocol == HslCommunicationCode.Hsl_Protocol_Client_Quit) { TcpStateDownLine(receive, true); } else if (protocol == HslCommunicationCode.Hsl_Protocol_User_Bytes) { //接收到字节数据 AcceptByte?.Invoke(receive, customer, content); LogNet?.WriteDebug("Protocol:" + protocol + " customer:" + customer + " name:" + receive.LoginAlias); } else if (protocol == HslCommunicationCode.Hsl_Protocol_User_String) { //接收到文本数据 string str = Encoding.Unicode.GetString(content); AcceptString?.Invoke(receive, customer, str); LogNet?.WriteDebug("Protocol:" + protocol + " customer:" + customer + " name:" + receive.LoginAlias); } }
private void ConnectFailed( ) { ConnectFailedCount++; Interlocked.Exchange(ref isConnecting, 0); LoginFailed?.Invoke(ConnectFailedCount); LogNet?.WriteDebug(ToString( ), "Connected Failed, Times: " + ConnectFailedCount); }
/// <summary> /// 心跳线程的方法 /// </summary> private void ThreadHeartCheck() { Thread.Sleep(2000); while (true) { Thread.Sleep(1000); if (!IsQuie) { byte[] send = new byte[16]; BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(send, 0); SendBytes(stateone, NetSupport.CommandBytes(HslProtocol.ProtocolCheckSecends, 0, KeyToken, send)); double timeSpan = (DateTime.Now - stateone.HeartTime).TotalSeconds; if (timeSpan > 1 * 8)//8次没有收到失去联系 { LogNet?.WriteDebug(LogHeaderText, $"Heart Check Failed int {timeSpan} Seconds."); ReconnectServer(); Thread.Sleep(1000); } } else { break; } } }
/// <summary> /// 心跳线程的方法 /// </summary> private void ThreadHeartCheck() { Thread.Sleep(2000); while (true) { Thread.Sleep(1000); if (!IsQuie) { byte[] send = new byte[16]; BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(send, 0); SendBytes(session, HslProtocol.CommandBytes(HslProtocol.ProtocolCheckSecends, 0, Token, send)); double timeSpan = (DateTime.Now - session.HeartTime).TotalSeconds; if (timeSpan > 1 * 8)//8次没有收到失去联系 { if (isConnecting == 0) { LogNet?.WriteDebug(ToString( ), $"Heart Check Failed int {timeSpan} Seconds."); ReconnectServer( ); } if (!IsQuie) { Thread.Sleep(1000); } } } else { break; } } }
// private bool Is_reconnect_server = false; // private object lock_reconnect_server = new object(); private void ReconnectServer() { // 是否连接服务器中,已经在连接的话,则不再连接 if (Is_Client_Connecting) { return; } // 是否退出了系统,退出则不再重连 if (IsQuie) { return; } LogNet?.WriteDebug(LogHeaderText, "Prepare ReConnect Server."); // 触发连接失败,重连系统前错误 BeforReConnected?.Invoke(); stateone.WorkSocket?.Close(); Thread thread_login = new Thread(new ThreadStart(ThreadLogin)) { IsBackground = true }; thread_login.Start(); }
/// <summary> /// 关闭该客户端引擎 /// </summary> public void ClientClose( ) { IsQuie = true; if (IsClientStart) { SendBytes(session, HslProtocol.CommandBytes(HslProtocol.ProtocolClientQuit, 0, Token, null)); } IsClientStart = false; // 关闭客户端 thread_heart_check = null; LoginSuccess = null; // 清空所有的事件 LoginFailed = null; MessageAlerts = null; AcceptByte = null; AcceptString = null; try { session.WorkSocket?.Shutdown(SocketShutdown.Both); session.WorkSocket?.Close( ); } catch { } LogNet?.WriteDebug(ToString( ), "Client Close."); }
/// <summary> /// 重写父类的数据交互方法,接收的时候采用标识符来接收 /// </summary> /// <param name="socket">套接字</param> /// <param name="send">发送的数据</param> /// <returns>发送结果对象</returns> public override OperateResult <byte[]> ReadFromCoreServer(Socket socket, byte[] send) { LogNet?.WriteDebug(ToString( ), StringResources.Language.Send + " : " + BasicFramework.SoftBasic.ByteToHexString(send, ' ')); // send OperateResult sendResult = Send(socket, send); if (!sendResult.IsSuccess) { socket?.Close( ); return(OperateResult.CreateFailedResult <byte[]>(sendResult)); } if (ReceiveTimeOut < 0) { return(OperateResult.CreateSuccessResult(new byte[0])); } // receive msg OperateResult <byte[]> resultReceive = NetSupport.ReceiveCommandLineFromSocket(socket, (byte)'\r', (byte)'\n'); if (!resultReceive.IsSuccess) { return(new OperateResult <byte[]>(StringResources.Language.ReceiveDataTimeout + ReceiveTimeOut)); } LogNet?.WriteDebug(ToString( ), StringResources.Language.Receive + " : " + BasicFramework.SoftBasic.ByteToHexString(resultReceive.Content, ' ')); // Success return(OperateResult.CreateSuccessResult(resultReceive.Content)); }
/// <summary> /// 当客户端的socket登录的时候额外检查的信息 /// </summary> /// <param name="socket">套接字</param> /// <param name="endPoint">终结点</param> /// <returns>验证的结果</returns> protected override OperateResult SocketAcceptExtraCheck(Socket socket, IPEndPoint endPoint) { if (IsUseAccountCertificate) { OperateResult <byte[], byte[]> receive = ReceiveAndCheckBytes(socket, 2000); if (!receive.IsSuccess) { return(new OperateResult(string.Format("Client login failed[{0}]", endPoint))); } if (BitConverter.ToInt32(receive.Content1, 0) != HslProtocol.ProtocolAccountLogin) { LogNet?.WriteError(ToString( ), StringResources.Language.NetClientAccountTimeout); socket?.Close( ); return(new OperateResult(string.Format("Client login failed[{0}]", endPoint))); } string[] infos = HslProtocol.UnPackStringArrayFromByte(receive.Content2); string ret = CheckAccountLegal(infos); SendStringAndCheckReceive(socket, ret == "success" ? 1 : 0, new string[] { ret }); if (ret != "success") { return(new OperateResult(string.Format("Client login failed[{0}]:{1}", endPoint, ret))); } LogNet?.WriteDebug(ToString( ), string.Format("Account Login:{0} Endpoint:[{1}]", infos[0], endPoint)); } return(OperateResult.CreateSuccessResult( )); }
private void ModbusHeadReveiveCallback(IAsyncResult ar) { if (ar.AsyncState is ModBusState state) { try { state.HeadByteReceivedLength += state.WorkSocket.EndReceive(ar); } catch (Exception ex) { // 关闭连接,记录日志 state.WorkSocket?.Close(); state = null; LogNet?.WriteException(LogHeaderText, "头子节接收失败!", ex); return; } if (state.HeadByteReceivedLength == 0) { // 断开连接 state.WorkSocket?.Close( ); state = null; LogNet?.WriteDebug(LogHeaderText, "Received Bytes, Closed Connection"); return; } if (state.HeadByteReceivedLength < state.HeadByte.Length) { // 数据不够,继续接收 state.WorkSocket.BeginReceive(state.HeadByte, state.HeadByteReceivedLength, state.HeadByte.Length - state.HeadByteReceivedLength, SocketFlags.None, new AsyncCallback(ModbusHeadReveiveCallback), state); return; } // 准备接收的数据长度 int ContentLength = state.HeadByte[4] * 256 + state.HeadByte[5]; // 第一次过滤,过滤掉不是Modbus Tcp协议的 if (state.HeadByte[2] == 0x00 && state.HeadByte[3] == 0x00 && ContentLength < 300) { // 头子节接收完成 state.Content = new byte[ContentLength]; state.ContentReceivedLength = 0; // 开始接收内容 state.WorkSocket.BeginReceive(state.Content, state.ContentReceivedLength, state.Content.Length - state.ContentReceivedLength, SocketFlags.None, new AsyncCallback(ModbusDataReveiveCallback), state); } else { // 关闭连接,记录日志 state.WorkSocket?.Close(); state = null; LogNet?.WriteDebug(LogHeaderText, "Received Bytes, but is was not modbus tcp protocols"); } } }
/// <summary> /// 套接字异步回调 /// </summary> /// <param name="ar"></param> private void SocketAsyncCallBack(IAsyncResult ar) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId.ToString("00")} SocketAsyncCallBack"); if (ar.AsyncState is AppSession session) { try { int receiveCount = session.WorkSocket.EndReceive(ar); S7Message s7Message = new S7Message(); OperateResult <byte[]> read1 = ReceiveByMessage(session.WorkSocket, int.MaxValue, s7Message); // 500 时间延长 if (!read1.IsSuccess) { LogNet?.WriteDebug(ToString(), string.Format(StringResources.Language.ClientOfflineInfo, session.IpEndPoint)); RemoveClient(session); return; } ; byte[] receive = read1.Content; if (receive[17] == 0x04) { // 读数据 session.WorkSocket.Send(ReadByMessage(receive)); } else if (receive[17] == 0x05) { // 写数据 session.WorkSocket.Send(WriteByMessage(receive)); } else if (receive[17] == 0x00) { // 请求订货号 session.WorkSocket.Send(SoftBasic.HexStringToBytes("03 00 00 7D 02 F0 80 32 07 00 00 00 01 00 0C 00 60 00 01 12 08 12 84 01 01 00 00 00 00 FF" + " 09 00 5C 00 11 00 00 00 1C 00 03 00 01 36 45 53 37 20 32 31 35 2D 31 41 47 34 30 2D 30 58 42 30 20 00 00 00 06 20 20 00 06 36 45 53 37 20" + " 32 31 35 2D 31 41 47 34 30 2D 30 58 42 30 20 00 00 00 06 20 20 00 07 36 45 53 37 20 32 31 35 2D 31 41 47 34 30 2D 30 58 42 30 20 00 00 56 04 02 01")); } else { session.WorkSocket.Close(); } RaiseDataReceived(receive); session.WorkSocket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(SocketAsyncCallBack), session); } catch { // 关闭连接,记录日志 session.WorkSocket?.Close(); LogNet?.WriteDebug(ToString(), string.Format(StringResources.Language.ClientOfflineInfo, session.IpEndPoint)); RemoveClient(session); return; } } }
private void AllDown(CoordinationStatus status) { // 此处没有取消和超时状态,直接完成 if (status == CoordinationStatus.AllDone) { Interlocked.Exchange(ref ConnectStatus, 0); LogNet?.WriteDebug("All bytes read complete."); OnReceivedData?.Invoke(BytesResult.ToArray()); } }
/// <summary> /// 处理请求接收连接后的方法 /// </summary> /// <param name="obj">Accpt对象</param> protected override void ThreadPoolLogin(object obj) { if (obj is Socket socket) { // 接收一条信息,指定当前请求的数据订阅信息的关键字 OperateResult <int, string> receive = ReceiveStringContentFromSocket(socket); if (!receive.IsSuccess) { return; } // 判断当前的关键字在服务器是否有消息发布 if (!IsPushGroupOnline(receive.Content2)) { SendStringAndCheckReceive(socket, 1, "当前订阅的关键字不存在"); LogNet?.WriteWarn(ToString( ), "当前订阅的关键字不存在"); socket?.Close( ); return; } SendStringAndCheckReceive(socket, 0, ""); // 允许发布订阅信息 AppSession session = new AppSession( ); session.KeyGroup = receive.Content2; session.WorkSocket = socket; try { session.IpEndPoint = (System.Net.IPEndPoint)socket.RemoteEndPoint; session.IpAddress = session.IpEndPoint.Address.ToString( ); } catch (Exception ex) { LogNet?.WriteException(ToString( ), "Ip信息获取失败", ex); } try { socket.BeginReceive(session.BytesHead, 0, session.BytesHead.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), session); } catch (Exception ex) { LogNet?.WriteException(ToString( ), "开启信息接收失败", ex); return; } LogNet?.WriteDebug(ToString( ), $"客户端 [ {session.IpEndPoint} ] 上线"); PushGroupClient push = GetPushGroupClient(receive.Content2); if (push != null) { System.Threading.Interlocked.Increment(ref onlineCount); push.AddPushClient(session); } } }
private void SocketAsyncCallBack(IAsyncResult ar) { if (ar.AsyncState is AppSession session) { try { int receiveCount = session.WorkSocket.EndReceive(ar); S7Message s7Message = new S7Message( ); OperateResult <S7Message> read1 = ReceiveMessage(session.WorkSocket, 5000, s7Message); if (!read1.IsSuccess) { LogNet?.WriteDebug(ToString( ), string.Format(StringResources.Language.ClientOfflineInfo, session.IpEndPoint)); return; } ; byte[] receive = SoftBasic.SpliceTwoByteArray(read1.Content.HeadBytes, read1.Content.ContentBytes); if (receive[17] == 0x04) { // 读数据 session.WorkSocket.Send(ReadByMessage(receive)); } else if (receive[17] == 0x05) { // 写数据 session.WorkSocket.Send(WriteByMessage(receive)); } else if (receive[17] == 0x00) { // 请求订货号 session.WorkSocket.Send(SoftBasic.HexStringToBytes("03 00 00 7D 02 F0 80 32 07 00 00 00 01 00 0C 00 60 00 01 12 08 12 84 01 01 00 00 00 00 FF" + " 09 00 5C 00 11 00 00 00 1C 00 03 00 01 36 45 53 37 20 32 31 35 2D 31 41 47 34 30 2D 30 58 42 30 20 00 00 00 06 20 20 00 06 36 45 53 37 20" + " 32 31 35 2D 31 41 47 34 30 2D 30 58 42 30 20 00 00 00 06 20 20 00 07 36 45 53 37 20 32 31 35 2D 31 41 47 34 30 2D 30 58 42 30 20 00 00 56 04 02 01")); } else { session.WorkSocket.Close( ); } RaiseDataReceived(receive); session.WorkSocket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(SocketAsyncCallBack), session); } catch { // 关闭连接,记录日志 session.WorkSocket?.Close( ); LogNet?.WriteDebug(ToString( ), string.Format(StringResources.Language.ClientOfflineInfo, session.IpEndPoint)); System.Threading.Interlocked.Decrement(ref onlineCount); RemoveClient(session); return; } } }
private void HeadReveiveCallBack(IAsyncResult ar) { if (ar.AsyncState is ModBusState state) { try { int count = state.WorkSocket.EndReceive(ar); state.HeadByteReceivedLength += count; if (state.HeadByteReceivedLength < state.HeadByte.Length) { // 数据不够,继续接收 state.WorkSocket.BeginReceive(state.HeadByte, state.HeadByteReceivedLength, state.HeadByte.Length - state.HeadByteReceivedLength, SocketFlags.None, new AsyncCallback(HeadReveiveCallBack), state); } else { // 第一次过滤,过滤掉不是Modbus Tcp协议的 if (state.HeadByte[2] == 0x00 && state.HeadByte[3] == 0x00) { // 头子节接收完成 int ContentLength = state.HeadByte[4] * 256 + state.HeadByte[5]; state.Content = new byte[ContentLength]; // 开始接收内容 state.WorkSocket.BeginReceive(state.Content, state.ContentReceivedLength, state.Content.Length - state.ContentReceivedLength, SocketFlags.None, new AsyncCallback(ContentReveiveCallBack), state); } else { // 关闭连接,记录日志 state.WorkSocket?.Close(); state = null; if (IsStarted) { LogNet?.WriteDebug("Received Bytes, but is was not modbus tcp"); } } } } catch (Exception ex) { // 关闭连接,记录日志 state.WorkSocket?.Close(); state = null; if (IsStarted) { LogNet?.WriteException("头子节接收失败!", ex); } } } }
private void SocketAsyncCallBack(IAsyncResult ar) { if (ar.AsyncState is AppSession session) { try { int receiveCount = session.WorkSocket.EndReceive(ar); LsisFastEnetMessage fastEnetMessage = new LsisFastEnetMessage(); OperateResult <byte[]> read1 = ReceiveByMessage(session.WorkSocket, 5000, fastEnetMessage); if (!read1.IsSuccess) { LogNet?.WriteDebug(ToString(), string.Format(StringResources.Language.ClientOfflineInfo, session.IpEndPoint)); RemoveClient(session); return; } ; byte[] receive = read1.Content; byte[] SendData = null; if (receive[20] == 0x54) { // 读数据 SendData = ReadByMessage(receive); RaiseDataReceived(SendData); session.WorkSocket.Send(SendData); } else if (receive[20] == 0x58) { SendData = WriteByMessage(receive); RaiseDataReceived(SendData); session.WorkSocket.Send(SendData); } else { session.WorkSocket.Close(); } RaiseDataSend(receive); session.WorkSocket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(SocketAsyncCallBack), session); } catch { // 关闭连接,记录日志 session.WorkSocket?.Close(); LogNet?.WriteDebug(ToString(), string.Format(StringResources.Language.ClientOfflineInfo, session.IpEndPoint)); RemoveClient(session); return; } } }
/// <summary> /// 当客户端登录后,进行Ip信息的过滤,然后触发本方法,也就是说之后的客户端需要,接收2次的握手协议 /// </summary> /// <param name="socket">网络套接字</param> /// <param name="endPoint">终端节点</param> protected override void ThreadPoolLoginAfterClientCheck(Socket socket, System.Net.IPEndPoint endPoint) { // 接收2次的握手协议 S7Message s7Message = new S7Message(); OperateResult <byte[]> read1 = ReceiveByMessage(socket, int.MaxValue, s7Message);//5000 时间延长,先接收第一条握手协议 Console.WriteLine($"接收:{Communication.BasicFramework.SoftBasic.ByteToHexString(read1.Content, ' ')}"); if (!read1.IsSuccess) { return; } OperateResult send1 = Send(socket, SoftBasic.HexStringToBytes("03 00 00 16 11 D0 00 01 00 0C 00 C0 01 0A C1 02 01 02 C2 02 01 00")); if (!send1.IsSuccess) { return; } OperateResult <byte[]> read2 = ReceiveByMessage(socket, int.MaxValue, s7Message);//5000 时间延长,再接收第二条握手协议 Console.WriteLine($"接收:{Communication.BasicFramework.SoftBasic.ByteToHexString(read2.Content, ' ')}"); if (!read1.IsSuccess) { return; } OperateResult send2 = Send(socket, SoftBasic.HexStringToBytes("03 00 00 1B 02 F0 80 32 03 00 00 04 00 00 08 00 00 00 00 F0 00 00 01 00 01 00 F0")); if (!read2.IsSuccess) { return; } // 开始接收数据信息 AppSession appSession = new AppSession(); appSession.IpEndPoint = endPoint; appSession.WorkSocket = socket; try { socket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(SocketAsyncCallBack), appSession);// 套接字异步回调 AddClient(appSession); } catch { socket.Close(); LogNet?.WriteDebug(ToString(), string.Format(StringResources.Language.ClientOfflineInfo, endPoint)); } }
/*********************************************************************************************************** * * 无法使用如下的字节头接收来确认网络传输,总是报错为最小 * ***********************************************************************************************************/ //private void ReceiveAsyncCallback(IAsyncResult ar) //{ // if (ar.AsyncState is AsyncStateOne state) // { // try // { // state.AlreadyReceivedHead += state.WorkSocket.EndReceiveFrom(ar, ref state.UdpEndPoint); // if (state.AlreadyReceivedHead < state.HeadLength) // { // //接续接收头数据 // WorkSocket.BeginReceiveFrom(state.BytesHead, state.AlreadyReceivedHead, state.HeadLength - state.AlreadyReceivedHead, SocketFlags.None, // ref state.UdpEndPoint, new AsyncCallback(ReceiveAsyncCallback), state); // } // else // { // //开始接收内容 // int ReceiveLenght = BitConverter.ToInt32(state.BytesHead, 4); // if (ReceiveLenght > 0) // { // state.BytesContent = new byte[ReceiveLenght]; // WorkSocket.BeginReceiveFrom(state.BytesContent, state.AlreadyReceivedContent, state.BytesContent.Length - state.AlreadyReceivedContent, // SocketFlags.None, ref state.UdpEndPoint, new AsyncCallback(ContentReceiveAsyncCallback), state); // } // else // { // //没有内容了 // ThreadDealWithReveice(state, BitConverter.ToInt32(state.BytesHead, 0), state.BytesContent); // state = null; // RefreshReceive(); // } // } // } // catch(Exception ex) // { // LogHelper.SaveError(StringResources.异步数据结束挂起发送出错, ex); // } // } //} //private void ContentReceiveAsyncCallback(IAsyncResult ar) //{ // if (ar.AsyncState is AsyncStateOne state) // { // try // { // state.AlreadyReceivedContent += state.WorkSocket.EndReceiveFrom(ar, ref state.UdpEndPoint); // if (state.AlreadyReceivedContent < state.BytesContent.Length) // { // //还需要继续接收 // WorkSocket.BeginReceiveFrom(state.BytesContent, state.AlreadyReceivedContent, state.BytesContent.Length - state.AlreadyReceivedContent, // SocketFlags.None, ref state.UdpEndPoint, new AsyncCallback(ContentReceiveAsyncCallback), state); // } // else // { // //接收完成了 // ThreadDealWithReveice(state, BitConverter.ToInt32(state.BytesHead, 0), new byte[0]); // state = null; // RefreshReceive(); // } // } // catch (Exception ex) // { // LogHelper.SaveError(StringResources.异步数据结束挂起发送出错, ex); // } // } //} #region 数据中心处理块 /// <summary> /// 数据处理中心 /// </summary> /// <param name="receive"></param> /// <param name="protocol"></param> /// <param name="customer"></param> /// <param name="content"></param> internal override void DataProcessingCenter(AsyncStateOne receive, int protocol, int customer, byte[] content) { LogNet?.WriteDebug(LogHeaderText, "Protocol:" + protocol + " customer:" + customer + " ip:" + receive.GetRemoteEndPoint().Address.ToString()); if (protocol == HslCommunicationCode.Hsl_Protocol_User_Bytes) { AcceptByte?.Invoke(receive, customer, content); } else if (protocol == HslCommunicationCode.Hsl_Protocol_User_String) { //接收到文本数据 string str = Encoding.Unicode.GetString(content); AcceptString?.Invoke(receive, customer, str); } }
/// <summary> /// 通信出错后的处理 /// </summary> /// <param name="receive">接收的会话</param> /// <param name="ex">异常</param> internal override void SocketReceiveException(AppSession receive, Exception ex) { if (ex.Message.Contains(StringResources.Language.SocketRemoteCloseException)) { // 异常掉线 ReconnectServer( ); } else { // MessageAlerts?.Invoke("数据接收出错:" + ex.Message); } LogNet?.WriteDebug(ToString( ), "Socket Excepiton Occured."); }
/// <summary> /// 通信出错后的处理 /// </summary> /// <param name="receive"></param> /// <param name="ex"></param> internal override void SocketReceiveException(AsyncStateOne receive, Exception ex) { if (ex.Message.Contains(StringResources.SocketRemoteCloseException)) { // 异常掉线 ReconnectServer(); } else { // MessageAlerts?.Invoke("数据接收出错:" + ex.Message); } LogNet?.WriteDebug(LogHeaderText, "Socket Excepiton Occured."); }
/// <summary> /// 当客户端登录后,进行Ip信息的过滤,然后触发本方法,也就是说之后的客户端需要 /// </summary> /// <param name="socket">网络套接字</param> /// <param name="endPoint">终端节点</param> protected override void ThreadPoolLoginAfterClientCheck(Socket socket, System.Net.IPEndPoint endPoint) { // 接收2次的握手协议 S7Message s7Message = new S7Message( ); OperateResult <S7Message> read1 = ReceiveMessage(socket, 5000, s7Message); if (!read1.IsSuccess) { return; } OperateResult send1 = Send(socket, SoftBasic.HexStringToBytes("03 00 00 16 11 D0 00 01 00 0C 00 C0 01 0A C1 02 01 02 C2 02 01 00")); if (!send1.IsSuccess) { return; } OperateResult <S7Message> read2 = ReceiveMessage(socket, 5000, s7Message); if (!read1.IsSuccess) { return; } OperateResult send2 = Send(socket, SoftBasic.HexStringToBytes("03 00 00 1B 02 F0 80 32 03 00 00 04 00 00 08 00 00 00 00 F0 00 00 01 00 01 00 F0")); if (!read2.IsSuccess) { return; } // 开始接收数据信息 AppSession appSession = new AppSession( ); appSession.IpEndPoint = endPoint; appSession.WorkSocket = socket; try { socket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(SocketAsyncCallBack), appSession); System.Threading.Interlocked.Increment(ref onlineCount); AddClient(appSession); } catch { socket.Close( ); LogNet?.WriteDebug(ToString( ), string.Format(StringResources.Language.ClientOfflineInfo, endPoint)); } }
/// <summary> /// 在长连接模式下,断开服务器的连接,并切换到短连接模式 /// </summary> /// <returns>关闭连接,不需要查看IsSuccess属性查看</returns> public OperateResult ConnectClose( ) { OperateResult result = new OperateResult( ); IsPersistentConn = false; // 额外操作 result = ExtraOnDisconnect(CoreSocket); // 关闭信息 CoreSocket?.Close( ); CoreSocket = null; LogNet?.WriteDebug(ToString( ), StringResources.NetEngineClose); return(result); }
/// <summary> /// 当客户端登录后,进行Ip信息的过滤,然后触发本方法,也就是说之后的客户端需要 /// </summary> /// <param name="socket">网络套接字</param> /// <param name="endPoint">终端节点</param> protected override void ThreadPoolLoginAfterClientCheck(Socket socket, System.Net.IPEndPoint endPoint) { // 开始接收数据信息 AppSession appSession = new AppSession(); appSession.IpEndPoint = endPoint; appSession.WorkSocket = socket; try { socket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(SocketAsyncCallBack), appSession); AddClient(appSession); } catch { socket.Close(); LogNet?.WriteDebug(ToString(), string.Format(StringResources.Language.ClientOfflineInfo, endPoint)); } }
/// <summary> /// 用于登录的回调方法 /// </summary> /// <param name="obj">socket对象</param> private void ThreadPoolLogin(object obj) { if (obj is Socket socket) { IPEndPoint endPoint = (IPEndPoint)socket.RemoteEndPoint; OperateResult check = SocketAcceptExtraCheck(socket, endPoint); if (!check.IsSuccess) { LogNet?.WriteDebug(ToString( ), check.Message); socket?.Close( ); } else { ThreadPoolLogin(socket, endPoint); } } }
/// <summary> /// 在长连接模式下,断开服务器的连接,并切换到短连接模式 /// </summary> /// <returns>关闭连接,不需要查看IsSuccess属性查看</returns> /// <example> /// 直接关闭连接即可,基本上是不需要进行成功的判定 /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Core\NetworkDoubleBase.cs" region="ConnectCloseExample" title="关闭连接结果" /> /// </example> public OperateResult ConnectClose( ) { OperateResult result = new OperateResult( ); isPersistentConn = false; InteractiveLock.Enter( ); // 额外操作 result = ExtraOnDisconnect(CoreSocket); // 关闭信息 CoreSocket?.Close( ); CoreSocket = null; InteractiveLock.Leave( ); LogNet?.WriteDebug(ToString( ), StringResources.Language.NetEngineClose); return(result); }
/// <summary> /// 当接收到了新的请求的时候执行的操作 /// </summary> /// <param name="obj"></param> protected override void ThreadPoolLogin(object obj) { // 为了提高系统的响应能力,采用异步来实现,即时有数万台设备接入也能应付 if (obj is Socket socket) { ModBusState state = new ModBusState( ) { WorkSocket = socket, }; try { state.IpEndPoint = (System.Net.IPEndPoint)socket.RemoteEndPoint; state.IpAddress = state.IpEndPoint.Address.ToString( ); } catch (Exception ex) { LogNet?.WriteException(ToString( ), "Ip信息获取失败", ex); } if (IsTrustedClientsOnly) { // 检查受信任的情况 if (!CheckIpAddressTrusted(state.IpAddress)) { // 客户端不被信任,退出 LogNet?.WriteDebug(ToString( ), $"客户端 [ {state.IpEndPoint} ] 不被信任,禁止登录!"); state.WorkSocket.Close( ); return; } } LogNet?.WriteDebug(ToString( ), $"客户端 [ {state.IpEndPoint} ] 上线"); try { state.WorkSocket.BeginReceive(state.HeadByte, 0, 6, SocketFlags.None, new AsyncCallback(ModbusHeadReveiveCallback), state); } catch (Exception ex) { state.WorkSocket?.Close( ); LogNet?.WriteException(ToString(), $"客户端 [ {state.IpEndPoint} ] 头子节接收失败!", ex); state = null; } } }
private void SocketAsyncCallBack(IAsyncResult ar) { if (ar.AsyncState is AppSession session) { try { int receiveCount = session.WorkSocket.EndReceive(ar); ModbusTcpMessage mdMessage = new ModbusTcpMessage( ); OperateResult <byte[]> read1 = ReceiveByMessage(session.WorkSocket, 5000, mdMessage); if (!read1.IsSuccess) { LogNet?.WriteDebug(ToString( ), string.Format(StringResources.Language.ClientOfflineInfo, session.IpEndPoint)); RemoveClient(session); return; } ; ushort id = (ushort)(read1.Content[0] * 256 + read1.Content[1]); byte[] back = ModbusInfo.PackCommandToTcp(ReadFromModbusCore(SoftBasic.BytesArrayRemoveBegin(read1.Content, 6)), id); if (back != null) { session.WorkSocket.Send(back); } else { session.WorkSocket.Close( ); RemoveClient(session); return; } RaiseDataReceived(read1.Content); session.WorkSocket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(SocketAsyncCallBack), session); } catch { // 关闭连接,记录日志 session.WorkSocket?.Close( ); LogNet?.WriteDebug(ToString( ), string.Format(StringResources.Language.ClientOfflineInfo, session.IpEndPoint)); RemoveClient(session); return; } } }