using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; using System.Threading; using System.IO; using System.Security.Cryptography; using System.Drawing; using HslCommunication.BasicFramework; using HslCommunication.LogNet; using HslCommunication.Core; namespace HslCommunication.Enthernet { /// /// 文件管理类服务器,负责服务器所有分类文件的管理,特点是不支持文件附加数据,但是支持直接访问文件名 /// public class AdvancedFileServer : HslCommunication.Core.Net.NetworkFileServerBase { #region Constructor /// /// 实例化一个对象 /// public AdvancedFileServer( ) { } #endregion #region Override Method /// /// 处理数据 /// /// protected override void ThreadPoolLogin( object obj ) { if (obj is Socket) { Socket socket = (Socket)obj; OperateResult result = new OperateResult( ); // 获取ip地址 string IpAddress = ((IPEndPoint)(socket.RemoteEndPoint)).Address.ToString( ); // 接收操作信息 int customer; string fileName; string Factory; string Group; string Identify; OperateResult infoResult = ReceiveInformationHead( socket, out customer, out fileName, out Factory, out Group, out 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.FileDownloadFailed}:{relativeName} ip:{IpAddress} 原因:{sendFile.Message}" ); return; } else { socket?.Close( ); LogNet?.WriteInfo( ToString( ), StringResources.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( ), "创建文件夹失败:" + fullFileName, ex ); socket?.Close( ); return; } string FileName; // 文件名称,从客户端上传到服务器时,为上传人 long FileSize; string FileTag; string FileUpload; OperateResult receiveFile = ReceiveFileFromSocketAndMoveFile( socket, // 网络套接字 tempFileName, // 临时保存文件路径 fullFileName, // 最终保存文件路径 out FileName, // 文件名称,从客户端上传到服务器时,为上传人 out FileSize, out FileTag, out FileUpload ); if (receiveFile.IsSuccess) { socket?.Close( ); LogNet?.WriteInfo( ToString( ), StringResources.FileUploadSuccess + ":" + relativeName ); } else { LogNet?.WriteInfo( ToString( ), StringResources.FileUploadFailed + ":" + relativeName + " 原因:" + 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 ? "成功" : "失败" // 字符串数据 ).IsSuccess) { socket?.Close( ); } if (deleteResult) LogNet?.WriteInfo( ToString( ), StringResources.FileDeleteSuccess + ":" + relativeName ); } else if (customer == HslProtocol.ProtocolFileDirectoryFiles) { List fileNames = new List( ); 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 folders = new List( ); 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( ); } } } /// /// 初始化数据 /// protected override void StartInitialization( ) { if (string.IsNullOrEmpty( FilesDirectoryPathTemp )) { throw new ArgumentNullException( "FilesDirectoryPathTemp", "No saved path is specified" ); } base.StartInitialization( ); } /// /// 检查文件夹 /// protected override void CheckFolderAndCreate( ) { if (!Directory.Exists( FilesDirectoryPathTemp )) { Directory.CreateDirectory( FilesDirectoryPathTemp ); } base.CheckFolderAndCreate( ); } /// /// 从网络套接字接收文件并移动到目标的文件夹中,如果结果异常,则结束通讯 /// /// /// /// /// /// /// /// /// private OperateResult ReceiveFileFromSocketAndMoveFile( Socket socket, string savename, string fileNameNew, out string filename, out long size, out string filetag, out string fileupload ) { // 先接收文件 OperateResult fileInfo = ReceiveFileFromSocket( socket, savename, null ); if (!fileInfo.IsSuccess) { DeleteFileByName( savename ); filename = null; size = 0; filetag = null; fileupload = null; return fileInfo; } filename = fileInfo.Content.Name; size = fileInfo.Content.Size; filetag = fileInfo.Content.Tag; fileupload = fileInfo.Content.Upload; // 标记移动文件,失败尝试三次 int customer = 0; int times = 0; while (times < 3) { times++; if (MoveFileToNewFile( savename, fileNameNew )) { customer = 1; break; } else { Thread.Sleep( 500 ); } } if (customer == 0) { DeleteFileByName( savename ); } // 回发消息 OperateResult sendString = SendStringAndCheckReceive( socket, customer, "success" ); return sendString; } #endregion #region Public Method /// /// 用于接收上传文件时的临时文件夹,临时文件使用结束后会被删除 /// public string FilesDirectoryPathTemp { get { return m_FilesDirectoryPathTemp; } set { m_FilesDirectoryPathTemp = PreprocessFolderName( value ); } } #endregion #region Private Member private string m_FilesDirectoryPathTemp = null; #endregion #region Object Override /// /// 获取本对象的字符串标识形式 /// /// public override string ToString() { return "AdvancedFileServer"; } #endregion } }