/// <summary> /// [自校验] 从网络中接收一个字符串数据,如果结果异常,则结束通讯 /// </summary> /// <param name="socket">套接字</param> /// <returns></returns> protected OperateResult <int, string> ReceiveStringContentFromSocket(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.ProtocolUserString) { LogNet?.WriteError(ToString( ), StringResources.CommandHeadCodeCheckFailed); socket?.Close( ); return(new OperateResult <int, string>( ) { Message = StringResources.CommandHeadCodeCheckFailed }); } if (receive.Content2 == null) { receive.Content2 = new byte[0]; } // 分析数据 return(OperateResult.CreateSuccessResult(BitConverter.ToInt32(receive.Content1, 4), Encoding.Unicode.GetString(receive.Content2))); }
/// <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( )); }
/// <summary> /// [自校验] 从网络中接收一串字节数据,如果结果异常,则结束通讯 /// </summary> /// <param name="socket">套接字</param> /// <returns></returns> protected OperateResult <int, byte[]> ReceiveBytesContentFromSocket(Socket socket) { OperateResult <byte[], byte[]> receive = ReceiveAndCheckBytes(socket, 10000); if (!receive.IsSuccess) { return(new OperateResult <int, byte[]>( ) { Message = receive.Message }); } // 检查是否是字节信息 if (BitConverter.ToInt32(receive.Content1, 0) != HslProtocol.ProtocolUserBytes) { LogNet?.WriteError(ToString( ), StringResources.CommandHeadCodeCheckFailed); socket?.Close( ); return(new OperateResult <int, byte[]>( ) { Message = StringResources.CommandHeadCodeCheckFailed }); } // 分析数据 return(OperateResult.CreateSuccessResult(BitConverter.ToInt32(receive.Content1, 4), receive.Content2)); }
/// <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> /// 异步传入的连接申请请求 /// </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); } } }
/// <summary> /// 接收一条完整的数据,使用异步接收完成,包含了指令头信息 /// </summary> /// <param name="socket">已经打开的网络套接字</param> /// <returns>数据的接收结果对象</returns> protected OperateResult <TNetMessage> ReceiveMessage(Socket socket) { TNetMessage netMsg = new TNetMessage(); OperateResult <TNetMessage> result = new OperateResult <TNetMessage>(); // 接收指令头 OperateResult <byte[]> headResult = Receive(socket, netMsg.ProtocolHeadBytesLength); if (!headResult.IsSuccess) { result.CopyErrorFromOther(headResult); return(result); } netMsg.HeadBytes = headResult.Content; if (!netMsg.CheckHeadBytesLegal(Token.ToByteArray())) { // 令牌校验失败 socket?.Close(); LogNet?.WriteError(ToString(), StringResources.TokenCheckFailed); result.Message = StringResources.TokenCheckFailed; return(result); } int contentLength = netMsg.GetContentLengthByHeadBytes(); if (contentLength == 0) { netMsg.ContentBytes = new byte[0]; } else { OperateResult <byte[]> contentResult = Receive(socket, contentLength); if (!headResult.IsSuccess) { result.CopyErrorFromOther(contentResult); return(result); } netMsg.ContentBytes = contentResult.Content; } result.Content = netMsg; result.IsSuccess = true; return(result); }
/// <summary> /// 接收到串口数据的时候触发 /// </summary> /// <param name="sender">串口对象</param> /// <param name="e">消息</param> private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { System.Threading.Thread.Sleep(20); // 此处做个微小的延时,等待数据接收完成 byte[] buffer = new byte[1024]; int count = serialPort.Read(buffer, 0, serialPort.BytesToRead); byte[] receive = new byte[count]; Array.Copy(buffer, 0, receive, 0, count); if (receive.Length < 3) { LogNet?.WriteError(ToString( ), $"Uknown Data:" + BasicFramework.SoftBasic.ByteToHexString(receive, ' ')); return; } if (Serial.SoftCRC16.CheckCRC16(receive)) { byte[] modbusCore = ModbusRtuTransModbusCore(receive); if (!CheckModbusMessageLegal(modbusCore)) { // 指令长度验证错误,关闭网络连接 LogNet?.WriteError(ToString( ), $"Receive Nosense Modbus-tcp : " + BasicFramework.SoftBasic.ByteToHexString(receive, ' ')); return; } // LogNet?.WriteError( ToString( ), $"Success:" + BasicFramework.SoftBasic.ByteToHexString( receive, ' ' ) ); // 需要回发消息 byte[] copy = ModbusCoreTransModbusRtu(ReadFromModbusCore(modbusCore)); serialPort.Write(copy, 0, copy.Length); } else { LogNet?.WriteWarn("CRC Check Failed : " + BasicFramework.SoftBasic.ByteToHexString(receive, ' ')); } }
/// <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="endPoint">终结点</param> protected override void ThreadPoolLogin(Socket socket, IPEndPoint endPoint) { OperateResult result = new OperateResult( ); // 获取ip地址 string IpAddress = ((IPEndPoint)(socket.RemoteEndPoint)).Address.ToString( ); // 接收操作信息 if (!ReceiveInformationHead( socket, out int customer, out string fileName, out string Factory, out string Group, out string Identify).IsSuccess) { return; } string relativeName = ReturnRelativeFileName(Factory, Group, Identify, fileName); if (customer == HslProtocol.ProtocolFileDownload) { // 先获取文件的真实名称 string guidName = TransformFactFileName(Factory, Group, Identify, fileName); // 获取文件操作锁 FileMarkId fileMarkId = GetFileMarksFromDictionaryWithFileName(guidName); fileMarkId.EnterReadOperator( ); // 发送文件数据 OperateResult send = SendFileAndCheckReceive(socket, ReturnAbsoluteFileName(Factory, Group, Identify, guidName), fileName, "", "", null); if (!send.IsSuccess) { fileMarkId.LeaveReadOperator( ); LogNet?.WriteError(ToString( ), $"{StringResources.Language.FileDownloadFailed} : {send.Message} :{relativeName} ip:{IpAddress}"); return; } else { LogNet?.WriteInfo(ToString( ), StringResources.Language.FileDownloadSuccess + ":" + relativeName); } fileMarkId.LeaveReadOperator( ); // 关闭连接 socket?.Close( ); } else if (customer == HslProtocol.ProtocolFileUpload) { string fullFileName = ReturnAbsoluteFileName(Factory, Group, Identify, fileName); // 上传文件 CheckFolderAndCreate( ); FileInfo info = new FileInfo(fullFileName); try { if (!Directory.Exists(info.DirectoryName)) { Directory.CreateDirectory(info.DirectoryName); } } catch (Exception ex) { LogNet?.WriteException(ToString( ), StringResources.Language.FilePathCreateFailed + fullFileName, ex); socket?.Close( ); return; } // 接收文件并回发消息 if (ReceiveFileFromSocketAndUpdateGroup( socket, // 网络套接字 fullFileName).IsSuccess) { socket?.Close( ); LogNet?.WriteInfo(ToString( ), StringResources.Language.FileUploadSuccess + ":" + relativeName); } else { LogNet?.WriteInfo(ToString( ), StringResources.Language.FileUploadFailed + ":" + relativeName); } } else if (customer == HslProtocol.ProtocolFileDelete) { string fullFileName = ReturnAbsoluteFileName(Factory, Group, Identify, fileName); FileInfo info = new FileInfo(fullFileName); GroupFileContainer fileManagment = GetGroupFromFilePath(info.DirectoryName); // 新增删除的任务 DeleteExsistingFile(info.DirectoryName, fileManagment.DeleteFile(info.Name)); // 回发消息 if (SendStringAndCheckReceive( socket, // 网络套接字 1, // 没啥含义 "success" // 没啥含意 ).IsSuccess) { socket?.Close( ); } LogNet?.WriteInfo(ToString( ), StringResources.Language.FileDeleteSuccess + ":" + relativeName); } else if (customer == HslProtocol.ProtocolFileDirectoryFiles) { GroupFileContainer fileManagment = GetGroupFromFilePath(ReturnAbsoluteFilePath(Factory, Group, Identify)); if (SendStringAndCheckReceive( socket, HslProtocol.ProtocolFileDirectoryFiles, fileManagment.JsonArrayContent).IsSuccess) { socket?.Close( ); } } else if (customer == HslProtocol.ProtocolFileDirectories) { List <string> folders = new List <string>( ); foreach (var m in GetDirectories(Factory, Group, Identify)) { DirectoryInfo directory = new DirectoryInfo(m); folders.Add(directory.Name); } Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.FromObject(folders.ToArray( )); if (SendStringAndCheckReceive( socket, HslProtocol.ProtocolFileDirectoryFiles, jArray.ToString( )).IsSuccess) { socket?.Close( ); } } else { // close not supported client socket?.Close( ); } }
/// <summary> /// 上传文件给服务器 /// </summary> /// <param name="source">数据源,可以是文件名,也可以是数据流</param> /// <param name="serverName">在服务器保存的文件名,不包含驱动器路径</param> /// <param name="factory">一级分类</param> /// <param name="group">二级分类</param> /// <param name="id">三级分类</param> /// <param name="fileTag">文件的描述</param> /// <param name="fileUpload">文件的上传人</param> /// <param name="processReport">汇报进度</param> /// <returns>是否成功的结果对象</returns> protected OperateResult UploadFileBase( object source, string serverName, string factory, string group, string id, string fileTag, string fileUpload, Action <long, long> processReport) { // 创建套接字并连接服务器 OperateResult <Socket> socketResult = CreateSocketAndConnect(ServerIpEndPoint, ConnectTimeOut); if (!socketResult.IsSuccess) { return(socketResult); } // 上传操作暗号的文件名 OperateResult sendString = SendStringAndCheckReceive(socketResult.Content, InsideProtocol.ProtocolFileUpload, serverName); if (!sendString.IsSuccess) { return(sendString); } // 发送三级分类 OperateResult sendClass = SendFactoryGroupId(socketResult.Content, factory, group, id); if (!sendClass.IsSuccess) { return(sendClass); } // 判断数据源格式 if (source is string fileName) { OperateResult result = SendFileAndCheckReceive(socketResult.Content, fileName, serverName, fileTag, fileUpload, processReport); if (!result.IsSuccess) { return(result); } } else if (source is Stream stream) { OperateResult result = SendFileAndCheckReceive(socketResult.Content, stream, serverName, fileTag, fileUpload, processReport); if (!result.IsSuccess) { return(result); } } else { socketResult.Content?.Close( ); LogNet?.WriteError(ToString( ), StringResources.Language.DataSourseFormatError); return(new OperateResult(StringResources.Language.DataSourseFormatError)); } // 确认服务器文件保存状态 OperateResult <int, string> resultCheck = ReceiveStringContentFromSocket(socketResult.Content); if (!resultCheck.IsSuccess) { return(resultCheck); } if (resultCheck.Content1 == 1) { return(OperateResult.CreateSuccessResult( )); } else { return(new OperateResult(StringResources.Language.ServerFileCheckFailed)); } }
/// <summary> /// 基础下载信息 /// </summary> /// <param name="factory">一级分类</param> /// <param name="group">二级分类</param> /// <param name="id">三级分类</param> /// <param name="fileName">服务器的文件名称</param> /// <param name="processReport">下载的进度报告</param> /// <param name="source">数据源信息,决定最终存储到哪里去</param> /// <returns>是否成功的结果对象</returns> protected OperateResult DownloadFileBase( string factory, string group, string id, string fileName, Action <long, long> processReport, object source ) { // connect server OperateResult <Socket> socketResult = CreateSocketAndConnect(ServerIpEndPoint, ConnectTimeOut); if (!socketResult.IsSuccess) { return(socketResult); } // 发送操作指令 OperateResult sendString = SendStringAndCheckReceive(socketResult.Content, InsideProtocol.ProtocolFileDownload, fileName); if (!sendString.IsSuccess) { return(sendString); } // 发送三级分类 OperateResult sendClass = SendFactoryGroupId(socketResult.Content, factory, group, id); if (!sendClass.IsSuccess) { return(sendClass); } // 根据数据源分析 if (source is string fileSaveName) { OperateResult result = ReceiveFileFromSocket(socketResult.Content, fileSaveName, processReport); if (!result.IsSuccess) { return(result); } } else if (source is Stream stream) { OperateResult result = ReceiveFileFromSocket(socketResult.Content, stream, processReport); if (!result.IsSuccess) { return(result); } } else { socketResult.Content?.Close( ); LogNet?.WriteError(ToString(), StringResources.Language.NotSupportedDataType); return(new OperateResult(StringResources.Language.NotSupportedDataType)); } socketResult.Content?.Close( ); return(OperateResult.CreateSuccessResult( )); }
/// <summary> /// 接收一条完整的数据,使用异步接收完成,包含了指令头信息 /// </summary> /// <param name="socket">已经打开的网络套接字</param> /// <param name="timeOut">超时时间</param> /// <param name="netMsg">消息规则</param> /// <returns>数据的接收结果对象</returns> protected OperateResult <TNetMessage> ReceiveMessage <TNetMessage>(Socket socket, int timeOut, TNetMessage netMsg) where TNetMessage : INetMessage { OperateResult <TNetMessage> result = new OperateResult <TNetMessage>(); // 超时接收的代码验证 HslTimeOut hslTimeOut = new HslTimeOut() { DelayTime = timeOut, WorkSocket = socket, }; if (timeOut > 0) { ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCheckTimeOut), hslTimeOut); } // 接收指令头 OperateResult <byte[]> headResult = Receive(socket, netMsg.ProtocolHeadBytesLength); if (!headResult.IsSuccess) { hslTimeOut.IsSuccessful = true; result.CopyErrorFromOther(headResult); return(result); } netMsg.HeadBytes = headResult.Content; if (!netMsg.CheckHeadBytesLegal(Token.ToByteArray())) { // 令牌校验失败 hslTimeOut.IsSuccessful = true; socket?.Close(); LogNet?.WriteError(ToString(), StringResources.TokenCheckFailed); result.Message = StringResources.TokenCheckFailed; return(result); } int contentLength = netMsg.GetContentLengthByHeadBytes(); if (contentLength == 0) { netMsg.ContentBytes = new byte[0]; } else { OperateResult <byte[]> contentResult = Receive(socket, contentLength); if (!headResult.IsSuccess) { hslTimeOut.IsSuccessful = true; result.CopyErrorFromOther(contentResult); return(result); } netMsg.ContentBytes = contentResult.Content; } // 防止没有实例化造成后续的操作失败 if (netMsg.ContentBytes == null) { netMsg.ContentBytes = new byte[0]; } hslTimeOut.IsSuccessful = true; result.Content = netMsg; result.IsSuccess = true; return(result); }
/// <summary> /// 基础下载信息 /// </summary> /// <param name="factory"></param> /// <param name="group"></param> /// <param name="id"></param> /// <param name="fileName">服务器的文件名称</param> /// <param name="processReport">下载的进度报告</param> /// <param name="source">数据源信息,决定最终存储到哪里去</param> /// <returns></returns> protected OperateResult DownloadFileBase( string factory, string group, string id, string fileName, Action <long, long> processReport, object source ) { OperateResult result = new OperateResult(); // connect server if (!CreateSocketAndConnect(out Socket socket, ServerIpEndPoint, result)) { return(result); } // 发送操作指令 if (!SendStringAndCheckReceive( socket, HslCommunicationCode.Hsl_Protocol_File_Download, fileName, result, null, "发送下载文件操作指令异常")) { return(result); } if (!SendFactoryGroupId( socket, factory, group, id, result)) { return(result); } // 根据数据源分析 if (source is string fileSaveName) { if (!ReceiveFileFromSocket( socket, fileSaveName, out string filename, out long filesize, out string filetag, out string fileupload, result, processReport, "下载文件的时候发生异常" )) { return(result); } } else if (source is Stream stream) { if (!ReceiveFileFromSocket( socket, stream, out string filename, out long filesize, out string filetag, out string fileupload, result, processReport, "下载文件的时候发生异常" )) { return(result); } } else { socket?.Close(); LogNet?.WriteError("Not supported data type!"); return(result); } socket?.Close(); result.IsSuccess = true; return(result); }
/// <summary> /// 接收到串口数据的时候触发 /// </summary> /// <param name="sender">串口对象</param> /// <param name="e">消息</param> private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { int rCount = 0; byte[] buffer = new byte[1024]; byte[] receive = null; while (true) { System.Threading.Thread.Sleep(20); // 此处做个微小的延时,等待数据接收完成 int count = serialPort.Read(buffer, rCount, serialPort.BytesToRead); rCount += count; if (count == 0) { break; } receive = new byte[rCount]; Array.Copy(buffer, 0, receive, 0, count); } if (receive == null) { return; } if (receive.Length < 3) { LogNet?.WriteError(ToString( ), $"Uknown Data:" + SoftBasic.ByteToHexString(receive, ' ')); return; } if (Serial.SoftCRC16.CheckCRC16(receive)) { byte[] modbusCore = SoftBasic.BytesArrayRemoveLast(receive, 2); if (!CheckModbusMessageLegal(modbusCore)) { // 指令长度验证错误,关闭网络连接 LogNet?.WriteError(ToString( ), $"Receive Nosense Modbus-rtu : " + SoftBasic.ByteToHexString(receive, ' ')); return; } // 验证站号是否一致 if (station >= 0 && station != modbusCore[0]) { LogNet?.WriteError(ToString( ), $"Station not match Modbus-rtu : " + SoftBasic.ByteToHexString(receive, ' ')); return; } // LogNet?.WriteError( ToString( ), $"Success:" + BasicFramework.SoftBasic.ByteToHexString( receive, ' ' ) ); // 需要回发消息 byte[] copy = ModbusInfo.PackCommandToRtu(ReadFromModbusCore(modbusCore)); serialPort.Write(copy, 0, copy.Length); if (IsStarted) { RaiseDataReceived(receive); } } else { LogNet?.WriteWarn("CRC Check Failed : " + SoftBasic.ByteToHexString(receive, ' ')); } }
private void ModbusDataReveiveCallback(IAsyncResult ar) { if (ar.AsyncState is ModBusState state) { try { state.ContentReceivedLength += state.WorkSocket.EndReceive(ar); if (state.ContentReceivedLength < state.Content.Length) { // 数据不够,继续接收 state.WorkSocket.BeginReceive(state.Content, state.ContentReceivedLength, state.Content.Length - state.ContentReceivedLength, SocketFlags.None, new AsyncCallback(ModbusDataReveiveCallback), state); return; } } catch (Exception ex) { // 关闭连接,记录日志 state.WorkSocket?.Close( ); LogNet?.WriteException(ToString(), $"客户端 [ {state.IpEndPoint} ] 下线,内容数据接收失败!", ex); return; } // 数据接收完成 // 内容接收完成,所有的数据接收结束 byte[] data = new byte[state.HeadByte.Length + state.Content.Length]; state.HeadByte.CopyTo(data, 0); state.Content.CopyTo(data, state.HeadByte.Length); state.Clear( ); byte[] modbusCore = ModbusTcpTransModbusCore(data); if (!CheckModbusMessageLegal(modbusCore)) { // 指令长度验证错误,关闭网络连接 state.WorkSocket?.Close( ); LogNet?.WriteError(ToString( ), $"客户端 [ {state.IpEndPoint} ] 下线,消息长度检查失败!"); return; } // 需要回发消息 byte[] copy = ModbusCoreTransModbusTcp(ReadFromModbusCore(modbusCore), data); try { // 管他是什么,先开始数据接收 // state.WorkSocket?.Close(); 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); return; } // 回发数据,先获取发送锁 state.hybirdLock.Enter( ); try { state.WorkSocket.BeginSend(copy, 0, size: copy.Length, socketFlags: SocketFlags.None, callback: new AsyncCallback(DataSendCallBack), state: state); } catch (Exception ex) { state.WorkSocket?.Close( ); state.hybirdLock.Leave( ); LogNet?.WriteException(ToString( ), $"客户端 [ {state.IpEndPoint} ] 异常下线,开始回发消息失败!", ex); return; } // 通知处理消息 if (IsStarted) { OnDataReceived?.Invoke(data); } } }
/// <summary> /// 上传文件给服务器 /// </summary> /// <param name="source">数据源,可以是文件名,也可以是数据流</param> /// <param name="serverName">在服务器保存的文件名,不包含驱动器路径</param> /// <param name="factory">一级分类</param> /// <param name="group">二级分类</param> /// <param name="id">三级分类</param> /// <param name="fileTag">文件的描述</param> /// <param name="fileUpload">文件的上传人</param> /// <param name="processReport">汇报进度</param> /// <returns>是否成功的结果对象</returns> protected OperateResult UploadFileBase( object source, string serverName, string factory, string group, string id, string fileTag, string fileUpload, Action <long, long> processReport) { // HslReadWriteLock readWriteLock = new HslReadWriteLock( ); // 创建套接字并连接服务器 OperateResult <Socket> socketResult = CreateSocketAndConnect(ServerIpEndPoint, ConnectTimeOut); if (!socketResult.IsSuccess) { return(socketResult); } // 上传操作暗号的文件名 OperateResult sendString = SendStringAndCheckReceive(socketResult.Content, HslProtocol.ProtocolFileUpload, serverName); if (!sendString.IsSuccess) { return(sendString); } // 发送三级分类 OperateResult sendClass = SendFactoryGroupId(socketResult.Content, factory, group, id); if (!sendClass.IsSuccess) { return(sendClass); } // 判断数据源格式 if (source is string fileName) { OperateResult result = SendFileAndCheckReceive(socketResult.Content, fileName, serverName, fileTag, fileUpload, processReport); if (!result.IsSuccess) { return(result); } } else if (source is Stream stream) { OperateResult result = SendFileAndCheckReceive(socketResult.Content, stream, serverName, fileTag, fileUpload, processReport); if (!result.IsSuccess) { return(result); } } else { socketResult.Content?.Close( ); LogNet?.WriteError(ToString( ), "数据源格式不正确!"); return(new OperateResult( ) { Message = "数据源格式不正确!", }); } // 确认服务器文件保存状态 OperateResult <int, string> resultCheck = ReceiveStringContentFromSocket(socketResult.Content); if (!resultCheck.IsSuccess) { return(resultCheck); } if (resultCheck.Content1 == 1) { return(OperateResult.CreateSuccessResult( )); } else { return(new OperateResult( ) { Message = "服务器确认文件失败,请重新上传!", }); } }
private void ModbusDataReveiveCallback(IAsyncResult ar) { if (ar.AsyncState is ModBusState state) { try { state.ContentReceivedLength += state.WorkSocket.EndReceive(ar); if (state.ContentReceivedLength < state.Content.Length) { // 数据不够,继续接收 state.WorkSocket.BeginReceive(state.Content, state.ContentReceivedLength, state.Content.Length - state.ContentReceivedLength, SocketFlags.None, new AsyncCallback(ModbusDataReveiveCallback), state); return; } } catch (Exception ex) { // 关闭连接,记录日志 state.WorkSocket?.Close( ); LogNet?.WriteException(ToString(), $"客户端 [ {state.IpEndPoint} ] 下线,内容数据接收失败!", ex); return; } // 数据接收完成 // 内容接收完成,所有的数据接收结束 byte[] data = new byte[state.HeadByte.Length + state.Content.Length]; state.HeadByte.CopyTo(data, 0); state.Content.CopyTo(data, state.HeadByte.Length); state.Clear( ); if (!CheckModbusMessageLegal(data)) { // 指令长度验证错误,关闭网络连接 state.WorkSocket?.Close( ); LogNet?.WriteError(ToString( ), $"客户端 [ {state.IpEndPoint} ] 下线,消息长度检查失败!"); return; } // 需要回发消息 byte[] copy = null; switch (data[7]) { case ModbusInfo.ReadCoil: { copy = ReadCoilBack(data); break; } case ModbusInfo.ReadRegister: { copy = ReadRegisterBack(data); break; } case ModbusInfo.WriteOneCoil: { copy = WriteOneCoilBack(data); break; } case ModbusInfo.WriteOneRegister: { copy = WriteOneRegisterBack(data); break; } case ModbusInfo.WriteCoil: { copy = WriteCoilsBack(data); break; } case ModbusInfo.WriteRegister: { copy = WriteRegisterBack(data); break; } default: { copy = CreateExceptionBack(data, ModbusInfo.FunctionCodeNotSupport); break; } } try { // 管他是什么,先开始数据接收 // state.WorkSocket?.Close(); 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); return; } // 回发数据,先获取发送锁 state.hybirdLock.Enter( ); try { state.WorkSocket.BeginSend(copy, 0, size: copy.Length, socketFlags: SocketFlags.None, callback: new AsyncCallback(DataSendCallBack), state: state); } catch (Exception ex) { state.WorkSocket?.Close( ); state.hybirdLock.Leave( ); LogNet?.WriteException(ToString( ), $"客户端 [ {state.IpEndPoint} ] 异常下线,开始回发消息失败!", ex); return; } // 通知处理消息 if (IsStarted) { OnDataReceived?.Invoke(data); } } }
/// <summary> /// 当接收到了新的请求的时候执行的操作 /// </summary> /// <param name="socket">异步对象</param> /// <param name="endPoint">终结点</param> protected override void ThreadPoolLogin(Socket socket, IPEndPoint endPoint) { OperateResult result = new OperateResult( ); // 获取ip地址 string IpAddress = ((IPEndPoint)(socket.RemoteEndPoint)).Address.ToString( ); // 接收操作信息 OperateResult infoResult = ReceiveInformationHead( socket, out int customer, out string fileName, out string Factory, out string Group, out string Identify); if (!infoResult.IsSuccess) { Console.WriteLine(infoResult.ToMessageShowString( )); return; } string relativeName = ReturnRelativeFileName(Factory, Group, Identify, fileName); // 操作分流 if (customer == HslProtocol.ProtocolFileDownload) { string fullFileName = ReturnAbsoluteFileName(Factory, Group, Identify, fileName); // 发送文件数据 OperateResult sendFile = SendFileAndCheckReceive(socket, fullFileName, fileName, "", ""); if (!sendFile.IsSuccess) { LogNet?.WriteError(ToString( ), $"{StringResources.Language.FileDownloadFailed}:{relativeName} ip:{IpAddress} reason:{sendFile.Message}"); return; } else { socket?.Close( ); LogNet?.WriteInfo(ToString( ), StringResources.Language.FileDownloadSuccess + ":" + relativeName); } } else if (customer == HslProtocol.ProtocolFileUpload) { string tempFileName = FilesDirectoryPathTemp + "\\" + CreateRandomFileName( ); string fullFileName = ReturnAbsoluteFileName(Factory, Group, Identify, fileName); // 上传文件 CheckFolderAndCreate( ); // 创建新的文件夹 try { FileInfo info = new FileInfo(fullFileName); if (!Directory.Exists(info.DirectoryName)) { Directory.CreateDirectory(info.DirectoryName); } } catch (Exception ex) { LogNet?.WriteException(ToString( ), StringResources.Language.FilePathCreateFailed + fullFileName, ex); socket?.Close( ); return; } OperateResult receiveFile = ReceiveFileFromSocketAndMoveFile( socket, // 网络套接字 tempFileName, // 临时保存文件路径 fullFileName, // 最终保存文件路径 out string FileName, // 文件名称,从客户端上传到服务器时,为上传人 out long FileSize, out string FileTag, out string FileUpload ); if (receiveFile.IsSuccess) { socket?.Close( ); LogNet?.WriteInfo(ToString( ), StringResources.Language.FileUploadSuccess + ":" + relativeName); } else { LogNet?.WriteInfo(ToString( ), StringResources.Language.FileUploadFailed + ":" + relativeName + " " + StringResources.Language.TextDescription + receiveFile.Message); } } else if (customer == HslProtocol.ProtocolFileDelete) { string fullFileName = ReturnAbsoluteFileName(Factory, Group, Identify, fileName); bool deleteResult = DeleteFileByName(fullFileName); // 回发消息 if (SendStringAndCheckReceive( socket, // 网络套接字 deleteResult ? 1 : 0, // 是否移动成功 deleteResult ? StringResources.Language.FileDeleteSuccess : StringResources.Language.FileDeleteFailed ).IsSuccess) { socket?.Close( ); } if (deleteResult) { LogNet?.WriteInfo(ToString( ), StringResources.Language.FileDeleteSuccess + ":" + relativeName); } } else if (customer == HslProtocol.ProtocolFileDirectoryFiles) { List <GroupFileItem> fileNames = new List <GroupFileItem>( ); foreach (var m in GetDirectoryFiles(Factory, Group, Identify)) { FileInfo fileInfo = new FileInfo(m); fileNames.Add(new GroupFileItem( ) { FileName = fileInfo.Name, FileSize = fileInfo.Length, }); } Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.FromObject(fileNames.ToArray( )); if (SendStringAndCheckReceive( socket, HslProtocol.ProtocolFileDirectoryFiles, jArray.ToString( )).IsSuccess) { socket?.Close( ); } } else if (customer == HslProtocol.ProtocolFileDirectories) { List <string> folders = new List <string>( ); foreach (var m in GetDirectories(Factory, Group, Identify)) { DirectoryInfo directory = new DirectoryInfo(m); folders.Add(directory.Name); } Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.FromObject(folders.ToArray( )); if (SendStringAndCheckReceive( socket, HslProtocol.ProtocolFileDirectoryFiles, jArray.ToString( )).IsSuccess) { socket?.Close( ); } } else { socket?.Close( ); } }
/// <summary> /// 处理数据 /// </summary> /// <param name="obj"></param> protected override void ThreadPoolLogin(object obj) { if (obj is Socket socket) { OperateResult result = new OperateResult(); // 获取ip地址 string IpAddress = ((IPEndPoint)(socket.RemoteEndPoint)).Address.ToString(); // 接收操作信息 if (!ReceiveInformationHead( socket, out int customer, out string fileName, out string Factory, out string Group, out string Identify, result, "filename received failed.ip:" + IpAddress )) { return; } string relativeName = ReturnRelativeFileName(Factory, Group, Identify, fileName); // 操作分流 if (customer == HslCommunicationCode.Hsl_Protocol_File_Download) { string fullFileName = ReturnAbsoluteFileName(Factory, Group, Identify, fileName); // 发送文件数据 if (!SendFileAndCheckReceive(socket, fullFileName, fileName, "", "", result, null)) { LogNet?.WriteError($"{StringResources.FileDownloadFailed}:{relativeName} ip:{IpAddress}"); return; } else { LogNet?.WriteInfo(StringResources.FileDownloadSuccess + ":" + relativeName); } socket?.Close(); } else if (customer == HslCommunicationCode.Hsl_Protocol_File_Upload) { string tempFileName = FilesDirectoryPathTemp + "\\" + CreateRandomFileName(); string fullFileName = ReturnAbsoluteFileName(Factory, Group, Identify, fileName); // 上传文件 CheckFolderAndCreate(); try { FileInfo info = new FileInfo(fullFileName); if (!Directory.Exists(info.DirectoryName)) { Directory.CreateDirectory(info.DirectoryName); } } catch (Exception ex) { LogNet?.WriteException("创建文件夹失败:" + fullFileName, ex); socket?.Close(); return; } if (ReceiveFileFromSocketAndMoveFile( socket, // 网络套接字 tempFileName, // 临时保存文件路径 fullFileName, // 最终保存文件路径 out string FileName, // 文件名称,从客户端上传到服务器时,为上传人 out long FileSize, out string FileTag, out string FileUpload, result )) { socket?.Close(); LogNet?.WriteInfo(StringResources.FileUploadSuccess + ":" + relativeName); } else { LogNet?.WriteInfo(StringResources.FileUploadFailed + ":" + relativeName); } } else if (customer == HslCommunicationCode.Hsl_Protocol_File_Delete) { string fullFileName = ReturnAbsoluteFileName(Factory, Group, Identify, fileName); bool deleteResult = DeleteFileByName(fullFileName); // 回发消息 if (SendStringAndCheckReceive( socket, // 网络套接字 deleteResult ? 1 : 0, // 是否移动成功 deleteResult ? "成功" : "失败", // 字符串数据 result, // 结果数据对象 null, // 不进行报告 "回发删除结果错误") // 发送错误时的数据 ) { socket?.Close(); } if (deleteResult) { LogNet?.WriteInfo(StringResources.FileDeleteSuccess + ":" + fullFileName); } } else if (customer == HslCommunicationCode.Hsl_Protocol_File_Directory_Files) { List <GroupFileItem> fileNames = new List <GroupFileItem>(); foreach (var m in GetDirectoryFiles(Factory, Group, Identify)) { FileInfo fileInfo = new FileInfo(m); fileNames.Add(new GroupFileItem() { FileName = fileInfo.Name, FileSize = fileInfo.Length, }); } Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.FromObject(fileNames.ToArray()); if (SendStringAndCheckReceive( socket, HslCommunicationCode.Hsl_Protocol_File_Directory_Files, jArray.ToString(), result, null, "发送文件列表回客户端失败")) { socket?.Close(); } } else if (customer == HslCommunicationCode.Hsl_Protocol_File_Directories) { List <string> folders = new List <string>(); foreach (var m in GetDirectories(Factory, Group, Identify)) { DirectoryInfo directory = new DirectoryInfo(m); folders.Add(directory.Name); } Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.FromObject(folders.ToArray()); if (SendStringAndCheckReceive( socket, HslCommunicationCode.Hsl_Protocol_File_Directory_Files, jArray.ToString(), result, null, "发送文件夹列表回客户端失败")) { socket?.Close(); } } else { socket?.Close(); } }
/// <summary> /// 上传文件给服务器 /// </summary> /// <param name="source">数据源,可以是文件名,也可以是数据流</param> /// <param name="serverName">在服务器保存的文件名,不包含驱动器路径</param> /// <param name="factory"></param> /// <param name="group"></param> /// <param name="id"></param> /// <param name="fileTag">文件的描述</param> /// <param name="fileUpload">文件的上传人</param> /// <param name="processReport">汇报进度</param> /// <returns></returns> protected OperateResult UploadFileBase( object source, string serverName, string factory, string group, string id, string fileTag, string fileUpload, Action <long, long> processReport) { OperateResult result = new OperateResult(); HslReadWriteLock readWriteLock = new HslReadWriteLock(); // 创建套接字并连接服务器 if (!CreateSocketAndConnect(out Socket socket, ServerIpEndPoint, result)) { return(result); } // 上传操作暗号的文件名 if (!SendStringAndCheckReceive( socket, HslCommunicationCode.Hsl_Protocol_File_Upload, serverName, result, null, "发送上传文件操作指令异常")) { return(result); } if (!SendFactoryGroupId( socket, factory, group, id, result)) { return(result); } // 判断数据源格式 if (source is string fileName) { if (!SendFileAndCheckReceive(socket, fileName, serverName, fileTag, fileUpload, result, processReport, "向服务器发送文件失败")) { return(result); } } else if (source is Stream stream) { if (!SendFileAndCheckReceive(socket, stream, serverName, fileTag, fileUpload, result, processReport, "向服务器发送文件失败")) { return(result); } } else { socket?.Close(); LogNet?.WriteError("source if not corrected!"); return(result); } // check the server result if (!ReceiveStringFromSocket(socket, out int status, out string nosense, result, null, "确认服务器保存状态失败")) { return(result); } socket?.Close(); if (status == 1) { result.IsSuccess = true; } else { result.Message = "服务器确认文件失败,请重新上传!"; } return(result); }