/// <summary> /// 接收服务器的反馈数据的规则 /// </summary> /// <param name="socket"></param> /// <param name="response"></param> /// <param name="result"></param> /// <returns></returns> protected override bool ReceiveResponse(Socket socket, out byte[] response, OperateResult result) { try { byte[] head = NetSupport.ReadBytesFromSocket(socket, 6); if (head[4] == 0x00 && head[5] == 0x00) { // 数据异常,再接收一个字节,防止有些比较坑的设备新增一个额外的字节来防止读取 for (int i = 0; i < head.Length - 1; i++) { head[i] = head[i + 1]; } socket.Receive(head, 5, 1, SocketFlags.None); } int length = head[4] * 256 + head[5]; byte[] data = NetSupport.ReadBytesFromSocket(socket, length); byte[] buffer = new byte[6 + length]; head.CopyTo(buffer, 0); data.CopyTo(buffer, 6); response = buffer; return(true); } catch (Exception ex) { LogNet?.WriteException(LogHeaderText, ex); socket?.Close(); response = null; result.Message = ex.Message; return(false); } }
/// <summary> /// 根据类型地址长度确认需要读取的指令头 /// </summary> /// <param name="address">起始地址</param> /// <param name="length">长度</param> /// <param name="isBit">是否是位读取</param> /// <returns>带有成功标志的指令数据</returns> private OperateResult<byte[]> BuildReadCommand( string address, ushort length ,bool isBit) { var result = new OperateResult<byte[]>( ); var analysis = AnalysisAddress( address, isBit ); if (!analysis.IsSuccess) return OperateResult.CreateFailedResult<byte[]>( analysis ); byte[] _PLCCommand = new byte[8]; _PLCCommand[0] = 0x01; // 读取存储区数据 _PLCCommand[1] = 0x01; if(isBit) { _PLCCommand[2] = analysis.Content1.BitCode; } else { _PLCCommand[2] = analysis.Content1.WordCode; } analysis.Content2.CopyTo( _PLCCommand, 3 ); _PLCCommand[6] = (byte)(length / 256); // 长度 _PLCCommand[7] = (byte)(length % 256); try { result.Content = PackCommand( _PLCCommand ); result.IsSuccess = true; } catch(Exception ex) { LogNet?.WriteException( ToString( ), ex ); result.Message = ex.Message; } return result; }
/***************************************************************************** * * 说明: * 下面的两个模块代码指示了如何读写文件 * ********************************************************************************/ #region Read Stream /// <summary> /// 读取流中的数据到缓存区 /// </summary> /// <param name="stream">数据流</param> /// <param name="buffer">缓冲区</param> /// <returns>带有成功标志的读取数据长度</returns> protected OperateResult <int> ReadStream(Stream stream, byte[] buffer) { ManualResetEvent WaitDone = new ManualResetEvent(false); FileStateObject stateObject = new FileStateObject( ); stateObject.WaitDone = WaitDone; stateObject.Stream = stream; stateObject.DataLength = buffer.Length; stateObject.Buffer = buffer; try { stream.BeginRead(buffer, 0, stateObject.DataLength, new AsyncCallback(ReadStreamCallBack), stateObject); } catch (Exception ex) { LogNet?.WriteException(ToString( ), ex); stateObject = null; WaitDone.Close( ); return(new OperateResult <int>( )); } WaitDone.WaitOne( ); WaitDone.Close( ); if (stateObject.IsError) { return(new OperateResult <int>( ) { Message = stateObject.ErrerMsg }); } else { return(OperateResult.CreateSuccessResult(stateObject.AlreadyDealLength)); } }
private byte[] WriteCoilsBack(byte[] modbus) { try { ushort address = ByteTransform.TransUInt16(modbus, 2); ushort length = ByteTransform.TransUInt16(modbus, 4); if ((address + length) > ushort.MaxValue + 1) { return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeOverBound)); } if (length > 2040) { return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeQuantityOver)); } byte[] buffer = new byte[modbus.Length - 7]; Array.Copy(modbus, 7, buffer, 0, buffer.Length); bool[] value = BasicFramework.SoftBasic.ByteToBoolArray(buffer, length); WriteCoil(address.ToString( ), value); return(CreateWriteBack(modbus)); } catch (Exception ex) { LogNet?.WriteException(ToString( ), StringResources.Language.ModbusTcpWriteCoilException, ex); return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeReadWriteException)); } }
/// <summary> /// 从目录进行加载数据,必须实例化的时候加载,加载失败会导致系统异常,旧的文件丢失 /// </summary> /// <param name="path"></param> private void GroupFileContainerLoadByPath(string path) { m_filePath = path; if (!Directory.Exists(m_filePath)) { Directory.CreateDirectory(m_filePath); } if (File.Exists(m_filePath + FileListResources)) { try { using (StreamReader sr = new StreamReader(m_filePath + FileListResources, Encoding.UTF8)) { m_files = Newtonsoft.Json.Linq.JArray.Parse(sr.ReadToEnd( )).ToObject <List <GroupFileItem> >( ); } } catch (Exception ex) { LogNet?.WriteException("GroupFileContainer", "Load files txt failed,", ex); } } if (m_files == null) { m_files = new List <GroupFileItem>( ); } coordinatorCacheJsonArray = new HslAsyncCoordinator(CacheJsonArrayContent); CacheJsonArrayContent( ); }
/// <summary> /// 发送数据异步返回的方法 /// </summary> /// <param name="ar"></param> private void SendCallBack(IAsyncResult ar) { if (ar.AsyncState is StateObject state) { try { Socket socket = state.WorkSocket; int byteSend = socket.EndSend(ar); state.AlreadyDealLength += byteSend; if (state.AlreadyDealLength < state.DataLength) { // 继续发送数据 socket.BeginSend(state.Buffer, state.AlreadyDealLength, state.DataLength - state.AlreadyDealLength, SocketFlags.None, new AsyncCallback(SendCallBack), state); } else { // 发送完成 state.WaitDone.Set( ); } } catch (Exception ex) { // 发生了异常 state.IsError = true; LogNet?.WriteException(ToString( ), ex); state.ErrerMsg = ex.Message; state.WaitDone.Set( ); } } }
private readonly byte endByte = 0x0D; // 结束的指令 #endregion /// <summary> /// 登录后的处理方法 /// </summary> /// <param name="obj"></param> protected override void ThreadPoolLogin(object obj) { if (obj is Socket socket) { // 登录成功 DeviceState stateone = new DeviceState( ) { WorkSocket = socket, DeviceEndPoint = (IPEndPoint)socket.RemoteEndPoint, IpAddress = ((IPEndPoint)socket.RemoteEndPoint).Address.ToString( ), ConnectTime = DateTime.Now, }; AddClient(stateone); try { stateone.WorkSocket.BeginReceive(stateone.Buffer, 0, stateone.Buffer.Length, SocketFlags.None, new AsyncCallback(ContentReceiveCallBack), stateone); } catch (Exception ex) { //登录前已经出错 RemoveClient(stateone); LogNet?.WriteException(ToString(), StringResources.Language.NetClientLoginFailed, ex); } } }
private byte[] ReadInputRegisterBack(byte[] modbus) { try { ushort address = ByteTransform.TransUInt16(modbus, 2); ushort length = ByteTransform.TransUInt16(modbus, 4); // 越界检测 if ((address + length) > ushort.MaxValue + 1) { return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeOverBound)); } // 地址长度检测 if (length > 127) { return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeQuantityOver)); } byte[] buffer = Read("x=4;" + address.ToString( ), length).Content; return(CreateReadBack(modbus, buffer)); } catch (Exception ex) { LogNet?.WriteException(ToString( ), StringResources.Language.ModbusTcpReadRegisterException, ex); return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeReadWriteException)); } }
private void ReceiveBufferCallback(IAsyncResult ar) { if (ar.AsyncState is StateObject state) { try { Socket client = state.WorkSocket; int bytesRead = client.EndReceive(ar); if (bytesRead > 0) { // 接收到了数据 state.AlreadyDealLength += bytesRead; } else { // 对方关闭了网络通讯 state.IsClose = true; } // 通知线程继续 state.WaitDone.Set( ); } catch (Exception ex) { state.IsError = true; LogNet?.WriteException(ToString( ), ex); state.ErrerMsg = ex.Message; state.WaitDone.Set( ); } } }
private void PlcConnectCallBack(IAsyncResult ar) { if (ar.AsyncState is PlcStateOne stateone) { try { stateone.WorkSocket.EndConnect(ar); stateone.WorkSocket.BeginReceive( stateone.PlcDataHead, stateone.LengthDataHead, stateone.PlcDataHead.Length - stateone.LengthDataHead, SocketFlags.None, new AsyncCallback(PlcHeadReceiveCallBack), stateone); stateone.IsConnect = true;// 指示访问成功 } catch (Exception ex) { LogNet?.WriteException("connect failed", ex); // 访问失败 stateone.WorkSocket.Close(); // 初始化数据 Array.Copy(ConnectWrongHead, 0, BytesResult, stateone.Index * EveryMachineLength, 2); // 更换端口 stateone.ChangePort(); // 结束任务 m_ac.JustEnded(); } } }
private byte[] ReadDiscreteBack(byte[] modbus) { try { ushort address = ByteTransform.TransUInt16(modbus, 2); ushort length = ByteTransform.TransUInt16(modbus, 4); // 越界检测 if ((address + length) > ushort.MaxValue + 1) { return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeOverBound)); } // 地址长度检测 if (length > 2040) { return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeQuantityOver)); } bool[] read = ReadDiscrete(address.ToString( ), length); byte[] buffer = BasicFramework.SoftBasic.BoolArrayToByte(read); return(CreateReadBack(modbus, buffer)); } catch (Exception ex) { LogNet?.WriteException(ToString( ), StringResources.Language.ModbusTcpReadCoilException, ex); return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeReadWriteException)); } }
/// <summary> /// 重新开始接收下一次的数据传递 /// </summary> /// <param name="session">网络状态</param> /// <param name="isProcess">是否触发数据处理</param> internal void ReBeginReceiveHead(AppSession session, bool isProcess) { try { byte[] head = session.BytesHead, Content = session.BytesContent; session.Clear( ); session.WorkSocket.BeginReceive(session.BytesHead, session.AlreadyReceivedHead, session.BytesHead.Length - session.AlreadyReceivedHead, SocketFlags.None, new AsyncCallback(HeadBytesReceiveCallback), session); // 检测是否需要数据处理 if (isProcess) { // 校验令牌 if (CheckRemoteToken(head)) { 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( ), StringResources.TokenCheckFailed); AppSessionRemoteClose(session); } } } catch (Exception ex) { SocketReceiveException(session, ex); LogNet?.WriteException(ToString( ), ex); } }
/// <summary> /// [自校验] 从网络中接收一个文件,写入数据流,如果结果异常,则结束通讯,参数顺序文件名,文件大小,文件标识,上传人 /// </summary> /// <param name="socket">网络套接字</param> /// <param name="stream">等待写入的数据流</param> /// <param name="receiveReport">接收进度报告</param> /// <returns></returns> protected OperateResult <FileBaseInfo> ReceiveFileFromSocket(Socket socket, Stream stream, Action <long, long> receiveReport) { // 先接收文件头信息 OperateResult <FileBaseInfo> fileResult = ReceiveFileHeadFromSocket(socket); if (!fileResult.IsSuccess) { return(fileResult); } try { WriteStream(socket, stream, fileResult.Content.Size, receiveReport, true); return(fileResult); } catch (Exception ex) { LogNet?.WriteException(ToString( ), ex); socket?.Close( ); return(new OperateResult <FileBaseInfo>( ) { Message = ex.Message }); } }
private void ReadStreamCallBack(IAsyncResult ar) { if (ar.AsyncState is FileStateObject stateObject) { try { stateObject.AlreadyDealLength += stateObject.Stream.EndRead(ar); if (stateObject.AlreadyDealLength < stateObject.DataLength) { // 继续读取剩余的数据 stateObject.Stream.BeginRead(stateObject.Buffer, stateObject.AlreadyDealLength, stateObject.DataLength - stateObject.AlreadyDealLength, new AsyncCallback(ReadStreamCallBack), stateObject); } else { stateObject.WaitDone.Set( ); } } catch (Exception ex) { LogNet?.WriteException(ToString( ), ex); stateObject.IsError = true; stateObject.ErrerMsg = ex.Message; stateObject.WaitDone.Set( ); } } }
/***************************************************************************** * * 说明: * 下面的三个模块代码指示了如何接收数据,如何发送数据,如何连接网络 * ********************************************************************************/ #region Reveive Content /// <summary> /// 接收固定长度的字节数组 /// </summary> /// <param name="socket">网络通讯的套接字</param> /// <param name="length">准备接收的数据长度</param> /// <returns>包含了字节数据的结果类</returns> protected OperateResult <byte[]> Receive(Socket socket, int length) { var result = new OperateResult <byte[]>( ); var receiveDone = new ManualResetEvent(false); var state = new StateObject(length); try { state.WaitDone = receiveDone; state.WorkSocket = socket; // Begin receiving the data from the remote device. socket.BeginReceive(state.Buffer, state.AlreadyDealLength, state.DataLength - state.AlreadyDealLength, SocketFlags.None, new AsyncCallback(ReceiveCallback), state); } catch (Exception ex) { // 发生了错误,直接返回 LogNet?.WriteException(ToString( ), ex); result.Message = ex.Message; receiveDone.Close( ); socket?.Close( ); return(result); } // 等待接收完成,或是发生异常 receiveDone.WaitOne( ); receiveDone.Close( ); // 接收数据失败 if (state.IsError) { socket?.Close( ); result.Message = state.ErrerMsg; return(result); } // 远程关闭了连接 if (state.IsClose) { result.IsSuccess = true; result.Message = "远程关闭了连接"; socket?.Close( ); return(result); } // 正常接收到数据 result.Content = state.Buffer; result.IsSuccess = true; state.Clear( ); state = null; return(result); }
private void SendAsyncCallBack(IAsyncResult ar) { if (ar.AsyncState is StateObjectAsync <bool> state) { try { Socket socket = state.WorkSocket; state.AlreadyDealLength += socket.EndSend(ar); if (state.AlreadyDealLength < state.DataLength) { // 继续发送数据 socket.BeginSend(state.Buffer, state.AlreadyDealLength, state.DataLength - state.AlreadyDealLength, SocketFlags.None, new AsyncCallback(SendAsyncCallBack), state); } else { // 发送完成 state.Tcs.SetResult(true); } } catch (Exception ex) { state.IsError = true; LogNet?.WriteException("SendAsyncCallBack", ex); state.Tcs.SetException(ex); } } }
/// <summary> /// 将缓冲区的数据写入到流里面去 /// </summary> /// <param name="stream">数据流</param> /// <param name="buffer">缓冲区</param> /// <returns>是否写入成功</returns> protected OperateResult WriteStream(Stream stream, byte[] buffer) { ManualResetEvent WaitDone = new ManualResetEvent(false); FileStateObject stateObject = new FileStateObject { WaitDone = WaitDone, Stream = stream }; try { stream.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(WriteStreamCallBack), stateObject); } catch (Exception ex) { LogNet?.WriteException(ToString( ), ex); stateObject = null; WaitDone.Close( ); return(new OperateResult( )); } WaitDone.WaitOne( ); WaitDone.Close( ); if (stateObject.IsError) { return(new OperateResult( ) { Message = stateObject.ErrerMsg }); } else { return(OperateResult.CreateSuccessResult( )); } }
/// <summary> /// 日志存储信息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { if (e.ExceptionObject is Exception ex) { LogNet?.WriteException("UnhandledException", ex); HslCommunication.BasicFramework.SoftMail.MailSystem163.SendMail(ex); } }
/// <summary> /// 发送消息给套接字,直到完成的时候返回 /// </summary> /// <param name="socket">网络套接字</param> /// <param name="data">字节数据</param> /// <returns>发送是否成功的结果</returns> protected OperateResult Send(Socket socket, byte[] data) { if (data == null) { return(OperateResult.CreateSuccessResult( )); } OperateResult result = new OperateResult( ); ManualResetEvent sendDone = null; StateObject state = null; try { sendDone = new ManualResetEvent(false); state = new StateObject(data.Length); } catch (Exception ex) { return(new OperateResult(ex.Message)); } try { state.WaitDone = sendDone; state.WorkSocket = socket; state.Buffer = data; socket.BeginSend(state.Buffer, state.AlreadyDealLength, state.DataLength - state.AlreadyDealLength, SocketFlags.None, new AsyncCallback(SendCallBack), state); } catch (Exception ex) { // 发生了错误,直接返回 LogNet?.WriteException(ToString( ), ex); result.Message = ex.Message; socket?.Close( ); sendDone.Close( ); return(result); } // 等待发送完成 sendDone.WaitOne( ); sendDone.Close( ); if (state.IsError) { socket.Close( ); result.Message = state.ErrerMsg; return(result); } state.Clear( ); state = null; result.IsSuccess = true; result.Message = StringResources.Language.SuccessText; return(result); }
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="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); } } }
/// <summary> /// 创建一个新的socket对象并连接到远程的地址 /// </summary> /// <param name="endPoint">连接的目标终结点</param> /// <param name="timeOut">连接的超时时间</param> /// <returns>返回套接字的封装结果对象</returns> /// <example> /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Core\NetworkBase.cs" region="CreateSocketAndConnectExample" title="创建连接示例" /> /// </example> protected OperateResult <Socket> CreateSocketAndConnect(IPEndPoint endPoint, int timeOut) { var result = new OperateResult <Socket>( ); var connectDone = new ManualResetEvent(false); var state = new StateObject( ); var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 超时验证的信息 HslTimeOut connectTimeout = new HslTimeOut( ) { WorkSocket = socket, DelayTime = timeOut }; ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), connectTimeout); try { state.WaitDone = connectDone; state.WorkSocket = socket; socket.BeginConnect(endPoint, new AsyncCallback(ConnectCallBack), state); } catch (Exception ex) { // 直接失败 connectTimeout.IsSuccessful = true; // 退出线程池的超时检查 LogNet?.WriteException(ToString( ), ex); // 记录错误日志 socket.Close( ); // 关闭网络信息 connectDone.Close( ); // 释放等待资源 result.Message = "Connect Failed : " + ex.Message; // 传递错误消息 return(result); } // 等待连接完成 connectDone.WaitOne( ); connectDone.Close( ); connectTimeout.IsSuccessful = true; if (state.IsError) { // 连接失败 result.Message = "Connect Failed : " + state.ErrerMsg; socket?.Close( ); return(result); } result.Content = socket; result.IsSuccess = true; state.Clear( ); state = null; return(result); }
private new void SendBytesAsync(AppSession session, byte[] data) { try { session.WorkSocket.SendTo(data, data.Length, SocketFlags.None, session.UdpEndPoint); } catch (Exception ex) { LogNet?.WriteException("SendMessage", ex); } }
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); } } } }
/// <summary> /// 异步传入的连接申请请求 /// </summary> /// <param name="iar"></param> protected void AsyncAcceptCallback(IAsyncResult iar) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId.ToString("00")} AsyncAcceptCallback"); //还原传入的原始套接字 if (iar.AsyncState is Socket server_socket) // 异步状态 { Socket client = null; try { // 在原始套接字上调用EndAccept方法,返回新的套接字 client = server_socket.EndAccept(iar); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolLogin), client);//将方法排入队列以便执行 用于登录的回调方法 } catch (ObjectDisposedException) { // 服务器关闭时候触发的异常,不进行记录 return; } catch (Exception ex) { // 有可能刚连接上就断开了,那就不管 client?.Close(); LogNet?.WriteException(ToString(), StringResources.Language.SocketAcceptCallbackException, ex); } // 如果失败,尝试启动三次 int i = 0; while (i < 3) { try { // AsyncAcceptCallback开始一个异步操作来接受一个传入的连接尝试 server_socket.BeginAccept(new AsyncCallback(AsyncAcceptCallback), server_socket); break; } catch (Exception ex) { Thread.Sleep(1000); LogNet?.WriteException(ToString(), StringResources.Language.SocketReAcceptCallbackException, ex); i++; } } if (i >= 3) { LogNet?.WriteError(ToString(), StringResources.Language.SocketReAcceptCallbackException); // 抛出异常,终止应用程序 throw new Exception(StringResources.Language.SocketReAcceptCallbackException); } } }
/// <summary> /// 检测当前的Modbus接收的指定是否是合法的 /// </summary> /// <param name="buffer">缓存数据</param> /// <returns>是否合格</returns> private bool CheckModbusMessageLegal(byte[] buffer) { try { if (buffer[1] == ModbusInfo.ReadCoil || buffer[1] == ModbusInfo.ReadDiscrete || buffer[1] == ModbusInfo.ReadRegister || buffer[1] == ModbusInfo.ReadInputRegister || buffer[1] == ModbusInfo.WriteOneCoil || buffer[1] == ModbusInfo.WriteOneRegister) { if (buffer.Length != 0x06) { return(false); } else { return(true); } } else if ( buffer[1] == ModbusInfo.WriteCoil || buffer[1] == ModbusInfo.WriteRegister) { if (buffer.Length < 7) { return(false); } else { if (buffer[6] == (buffer.Length - 7)) { return(true); } else { return(false); } } } else { return(true); } } catch (Exception ex) { LogNet?.WriteException(ToString( ), ex); return(false); } }
/// <summary> /// 数据内容接收方法 /// </summary> /// <param name="ar"></param> private void ContentReceiveCallback(IAsyncResult ar) { if (ar.AsyncState is AppSession receive) { try { receive.AlreadyReceivedContent += receive.WorkSocket.EndReceive(ar); } catch (ObjectDisposedException) { //不需要处理 return; } catch (SocketException ex) { //已经断开连接了 SocketReceiveException(receive, ex); LogNet?.WriteException(ToString( ), ex); return; } catch (Exception ex) { //其他乱七八糟的异常重新启用接收数据 ReBeginReceiveHead(receive, false); LogNet?.WriteException(ToString( ), StringResources.SocketEndReceiveException, ex); return; } if (receive.AlreadyReceivedContent < receive.BytesContent.Length) { int receiveSize = receive.BytesContent.Length - receive.AlreadyReceivedContent; try { //仍需要接收 receive.WorkSocket.BeginReceive(receive.BytesContent, receive.AlreadyReceivedContent, receiveSize, SocketFlags.None, new AsyncCallback(ContentReceiveCallback), receive); } catch (Exception ex) { ReBeginReceiveHead(receive, false); LogNet?.WriteException(ToString( ), StringResources.SocketEndReceiveException, ex); } } else { //处理数据并重新启动接收 ReBeginReceiveHead(receive, true); } } }
private void ContentReceiveCallBack(IAsyncResult ar) { if (ar.AsyncState is DeviceState stateone) { try { int count = stateone.WorkSocket.EndReceive(ar); if (count > 0) { MemoryStream ms = new MemoryStream( ); byte next = stateone.Buffer[0]; while (next != endByte) { ms.WriteByte(next); byte[] buffer = new byte[1]; stateone.WorkSocket.Receive(buffer, 0, 1, SocketFlags.None); next = buffer[0]; } // 接收完成 stateone.WorkSocket.BeginReceive(stateone.Buffer, 0, stateone.Buffer.Length, SocketFlags.None, new AsyncCallback(ContentReceiveCallBack), stateone); byte[] receive = ms.ToArray( ); ms.Dispose( ); lock_list.Enter( ); stateone.ReceiveTime = DateTime.Now; lock_list.Leave( ); AcceptBytes?.Invoke(stateone, receive); AcceptString?.Invoke(stateone, Encoding.ASCII.GetString(receive)); } else { RemoveClient(stateone); LogNet?.WriteInfo(ToString( ), StringResources.Language.NetClientOffline); } } catch (Exception ex) { //登录前已经出错 RemoveClient(stateone); LogNet?.WriteException(ToString( ), StringResources.Language.NetClientLoginFailed, ex); } } }
private byte[] WriteRegisterBack(byte[] modbus) { try { ushort address = ByteTransform.TransUInt16(modbus, 2); ushort length = ByteTransform.TransUInt16(modbus, 4); if ((address + length) > ushort.MaxValue + 1) { return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeOverBound)); } if (length > 127) { return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeQuantityOver)); } byte[] buffer = new byte[modbus.Length - 7]; // 为了使服务器的数据订阅更加的准确,决定将设计改为等待所有的数据写入完成后,再统一触发订阅,2018年3月4日 20:56:47 MonitorAddress[] addresses = new MonitorAddress[length]; for (ushort i = 0; i < length; i++) { short ValueOld = ReadInt16((address + i).ToString( )).Content; Write((address + i).ToString( ), modbus[2 * i + 7], modbus[2 * i + 8]); short ValueNew = ReadInt16((address + i).ToString( )).Content; // 触发写入请求 addresses[i] = new MonitorAddress( ) { Address = (ushort)(address + i), ValueOrigin = ValueOld, ValueNew = ValueNew }; } // 所有数据都更改完成后,再触发消息 for (int i = 0; i < addresses.Length; i++) { OnRegisterBeforWrite(addresses[i].Address, addresses[i].ValueOrigin, addresses[i].ValueNew); } return(CreateWriteBack(modbus)); } catch (Exception ex) { LogNet?.WriteException(ToString( ), StringResources.Language.ModbusTcpWriteRegisterException, ex); return(CreateExceptionBack(modbus, ModbusInfo.FunctionCodeReadWriteException)); } }
/// <summary> /// 异步传入的连接申请请求 /// </summary> /// <param name="iar"></param> protected void AsyncAcceptCallback(IAsyncResult iar) { //还原传入的原始套接字 if (iar.AsyncState is Socket server_socket) { Socket client = null; try { // 在原始套接字上调用EndAccept方法,返回新的套接字 client = server_socket.EndAccept(iar); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolLogin), client); } catch (ObjectDisposedException) { // 服务器关闭时候触发的异常,不进行记录 return; } catch (Exception ex) { // 有可能刚连接上就断开了,那就不管 client?.Close( ); LogNet?.WriteException(ToString(), StringResources.SocketAcceptCallbackException, ex); } // 如果失败,尝试启动三次 int i = 0; while (i < 3) { try { server_socket.BeginAccept(new AsyncCallback(AsyncAcceptCallback), server_socket); break; } catch (Exception ex) { Thread.Sleep(1000); LogNet?.WriteException(ToString( ), StringResources.SocketReAcceptCallbackException, ex); i++; } } if (i >= 3) { LogNet?.WriteError(ToString( ), StringResources.SocketReAcceptCallbackException); // 抛出异常,终止应用程序 throw new Exception(StringResources.SocketReAcceptCallbackException); } } }