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 UltimateFileServer : Core.Net.NetworkFileServerBase
{
#region Constructor
///
/// 实例化一个对象
///
public UltimateFileServer( )
{
}
#endregion
#region 文件列表存储器
///
/// 所有文件组操作的词典锁
///
internal Dictionary m_dictionary_group_marks = new Dictionary( );
///
/// 词典的锁
///
private SimpleHybirdLock hybirdLock = new SimpleHybirdLock( );
///
/// 获取当前目录的读写锁,如果没有会自动创建
///
/// 相对路径名
/// 读写锁
public GroupFileContainer GetGroupFromFilePath( string filePath )
{
GroupFileContainer GroupFile = null;
hybirdLock.Enter( );
// lock operator
if (m_dictionary_group_marks.ContainsKey( filePath ))
{
GroupFile = m_dictionary_group_marks[filePath];
}
else
{
GroupFile = new GroupFileContainer( LogNet, filePath );
m_dictionary_group_marks.Add( filePath, GroupFile );
}
hybirdLock.Leave( );
return GroupFile;
}
#endregion
#region 接收文件数据并更新文件列表
///
/// 从套接字接收文件并保存,更新文件列表
///
/// 套接字
/// 保存的文件名
///
private OperateResult ReceiveFileFromSocketAndUpdateGroup(
Socket socket,
string savename
)
{
FileInfo info = new FileInfo( savename );
string guidName = CreateRandomFileName( );
string fileName = info.DirectoryName + "\\" + guidName;
OperateResult receive = ReceiveFileFromSocket( socket, fileName, null );
if(!receive.IsSuccess)
{
DeleteFileByName( fileName );
return receive;
}
// 更新操作
GroupFileContainer fileManagment = GetGroupFromFilePath( info.DirectoryName );
string oldName = fileManagment.UpdateFileMappingName(
info.Name,
receive.Content.Size,
guidName,
receive.Content.Upload,
receive.Content.Tag
);
// 删除旧的文件
DeleteExsistingFile( info.DirectoryName, oldName );
// 回发消息
return SendStringAndCheckReceive( socket, 1, "成功" );
}
#endregion
#region Private Method
///
/// 根据文件的显示名称转化为真实存储的名称
///
/// 第一大类
/// 第二大类
/// 第三大类
/// 文件显示名称
///
private string TransformFactFileName( string factory, string group, string id, string fileName )
{
string path = ReturnAbsoluteFilePath( factory, group, id );
GroupFileContainer fileManagment = GetGroupFromFilePath( path );
return fileManagment.GetCurrentFileMappingName( fileName );
}
///
/// 删除已经存在的文件信息
///
///
///
private void DeleteExsistingFile( string path, string fileName )
{
if (!string.IsNullOrEmpty( fileName ))
{
string fileUltimatePath = path + "\\" + fileName;
FileMarkId fileMarkId = GetFileMarksFromDictionaryWithFileName( fileName );
fileMarkId.AddOperation( ( ) =>
{
if (!DeleteFileByName( fileUltimatePath ))
{
LogNet?.WriteInfo( ToString(), StringResources.FileDeleteFailed + fileUltimatePath );
}
} );
}
}
#endregion
#region Protect Override
///
/// 处理数据
///
///
protected override void ThreadPoolLogin( object obj )
{
if (obj is Socket)
{
Socket socket = obj as Socket;
OperateResult result = new OperateResult( );
// 获取ip地址
string IpAddress = ((IPEndPoint)(socket.RemoteEndPoint)).Address.ToString( );
// 接收操作信息
int customer;
string fileName;
string Factory;
string Group;
string Identify;
if (!ReceiveInformationHead(
socket,
out customer,
out fileName,
out Factory,
out Group,
out 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.FileDownloadFailed} : {send.Message} :{relativeName} ip:{IpAddress}" );
return;
}
else
{
LogNet?.WriteInfo( ToString( ), StringResources.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.FilePathCreateFailed + fullFileName, ex );
socket?.Close( );
return;
}
// 接收文件并回发消息
if (ReceiveFileFromSocketAndUpdateGroup(
socket, // 网络套接字
fullFileName ).IsSuccess)
{
socket?.Close( );
LogNet?.WriteInfo( ToString( ), StringResources.FileUploadSuccess + ":" + relativeName );
}
else
{
LogNet?.WriteInfo( ToString( ), StringResources.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.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 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
{
// close not supported client
socket?.Close( );
}
}
}
#endregion
#region Object Override
///
/// 获取本对象的字符串表示形式
///
///
public override string ToString( )
{
return "UltimateFileServer";
}
#endregion
}
}