|
|
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
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 文件管理类服务器,负责服务器所有分类文件的管理,特点是不支持文件附加数据,但是支持直接访问文件名
|
|
|
/// </summary>
|
|
|
/// <remarks>
|
|
|
/// 本文件的服务器不支持存储文件携带的额外信息,是直接将文件存放在服务器指定目录下的,文件名不更改,特点是服务器查看方便。
|
|
|
/// </remarks>
|
|
|
/// <example>
|
|
|
/// 以下的示例来自Demo项目,创建了一个简单的服务器对象。
|
|
|
/// <code lang="cs" source="TestProject\FileNetServer\FormFileServer.cs" region="Advanced Server" title="AdvancedFileServer示例" />
|
|
|
/// </example>
|
|
|
public class AdvancedFileServer : HslCommunication.Core.Net.NetworkFileServerBase
|
|
|
{
|
|
|
|
|
|
#region Constructor
|
|
|
|
|
|
/// <summary>
|
|
|
/// 实例化一个对象
|
|
|
/// </summary>
|
|
|
public AdvancedFileServer( )
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Override Method
|
|
|
|
|
|
/// <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>
|
|
|
protected override void StartInitialization( )
|
|
|
{
|
|
|
if (string.IsNullOrEmpty( FilesDirectoryPathTemp ))
|
|
|
{
|
|
|
throw new ArgumentNullException( "FilesDirectoryPathTemp", "No saved path is specified" );
|
|
|
}
|
|
|
|
|
|
base.StartInitialization( );
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 检查文件夹
|
|
|
/// </summary>
|
|
|
protected override void CheckFolderAndCreate( )
|
|
|
{
|
|
|
if (!Directory.Exists( FilesDirectoryPathTemp ))
|
|
|
{
|
|
|
Directory.CreateDirectory( FilesDirectoryPathTemp );
|
|
|
}
|
|
|
|
|
|
base.CheckFolderAndCreate( );
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 从网络套接字接收文件并移动到目标的文件夹中,如果结果异常,则结束通讯
|
|
|
/// </summary>
|
|
|
/// <param name="socket"></param>
|
|
|
/// <param name="savename"></param>
|
|
|
/// <param name="fileNameNew"></param>
|
|
|
/// <param name="filename"></param>
|
|
|
/// <param name="size"></param>
|
|
|
/// <param name="filetag"></param>
|
|
|
/// <param name="fileupload"></param>
|
|
|
/// <returns></returns>
|
|
|
private OperateResult ReceiveFileFromSocketAndMoveFile(
|
|
|
Socket socket,
|
|
|
string savename,
|
|
|
string fileNameNew,
|
|
|
out string filename,
|
|
|
out long size,
|
|
|
out string filetag,
|
|
|
out string fileupload
|
|
|
)
|
|
|
{
|
|
|
// 先接收文件
|
|
|
OperateResult<FileBaseInfo> 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
|
|
|
|
|
|
/// <summary>
|
|
|
/// 用于接收上传文件时的临时文件夹,临时文件使用结束后会被删除
|
|
|
/// </summary>
|
|
|
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
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取本对象的字符串标识形式
|
|
|
/// </summary>
|
|
|
/// <returns>字符串对象</returns>
|
|
|
public override string ToString()
|
|
|
{
|
|
|
return "AdvancedFileServer";
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
}
|