/******************************
* 说明:上传Socket通讯协议
* 创建人:龚宇超
* 创建日期:2018-01-23
* 修改人:
* 修改日期:
* 修改备注:
* 版本:1.0.0.0
******************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
namespace Lskj.SocketService
{
///
/// 上传Socket通讯协议
///
public class UploadSocketProtocol : BaseSocketProtocol
{
private string _fileName;
public string FileName { get { return _fileName; } }
private FileStream _fileStream;
public UploadSocketProtocol(AsyncSocketServer asyncSocketServer, AsyncSocketUserToken asyncSocketUserToken)
: base(asyncSocketServer, asyncSocketUserToken)
{
_socketFlag = "Upload";
_fileName = "";
_fileStream = null;
lock (_asyncSocketServer.UploadSocketProtocolMgr)
{
_asyncSocketServer.UploadSocketProtocolMgr.Add(this);
}
}
///
/// 说明:检查是否登录
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The command.
/// true if XXXX, false otherwise.
public bool CheckLogined(UploadSocketCommand command)
{
if ((command == UploadSocketCommand.Login) | (command == UploadSocketCommand.Active))
return true;
else
return _logined;
}
///
/// 说明:获取服务器目录
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// true if XXXX, false otherwise.
public bool DoDir()
{
string parentDir = "";
if (_incomingDataParser.GetValue(ProtocolKey.ParentDir, ref parentDir))
{
if (parentDir == "")
parentDir = SocketApp.FileDirectory;
else
parentDir = Path.Combine(SocketApp.FileDirectory, parentDir);
if (Directory.Exists(parentDir))
{
string[] subDirectorys = Directory.GetDirectories(parentDir, "*", SearchOption.TopDirectoryOnly);
_outgoingDataAssembler.AddSuccess();
char[] directorySeparator = new char[1];
directorySeparator[0] = Path.DirectorySeparatorChar;
for (int i = 0; i < subDirectorys.Length; i++)
{
string[] directoryName = subDirectorys[i].Split(directorySeparator, StringSplitOptions.RemoveEmptyEntries);
_outgoingDataAssembler.AddValue(ProtocolKey.Item, directoryName[directoryName.Length - 1]);
}
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.DirNotExist, "");
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");
return DoSendResult();
}
///
/// 说明:创建目录
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// true if XXXX, false otherwise.
public bool DoCreateDir()
{
string parentDir = "";
string dirName = "";
if (_incomingDataParser.GetValue(ProtocolKey.ParentDir, ref parentDir) & _incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName))
{
if (parentDir == "")
parentDir = SocketApp.FileDirectory;
else
parentDir = Path.Combine(SocketApp.FileDirectory, parentDir);
if (Directory.Exists(parentDir))
{
try
{
parentDir = Path.Combine(parentDir, dirName);
Directory.CreateDirectory(parentDir);
_outgoingDataAssembler.AddSuccess();
}
catch (Exception E)
{
_outgoingDataAssembler.AddFailure(ProtocolCode.CreateDirError, E.Message);
}
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.DirNotExist, "");
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");
return DoSendResult();
}
///
/// 说明:删除目录
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// true if XXXX, false otherwise.
public bool DoDeleteDir()
{
string parentDir = "";
string dirName = "";
if (_incomingDataParser.GetValue(ProtocolKey.ParentDir, ref parentDir) & _incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName))
{
if (parentDir == "")
parentDir = SocketApp.FileDirectory;
else
parentDir = Path.Combine(SocketApp.FileDirectory, parentDir);
if (Directory.Exists(parentDir))
{
try
{
parentDir = Path.Combine(parentDir, dirName);
Directory.Delete(parentDir, true);
_outgoingDataAssembler.AddSuccess();
}
catch (Exception E)
{
_outgoingDataAssembler.AddFailure(ProtocolCode.DeleteDirError, E.Message);
}
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.DirNotExist, "");
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");
return DoSendResult();
}
///
/// 说明:获取服务器文件列表
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// true if XXXX, false otherwise.
public bool DoFileList()
{
string dirName = "";
if (_incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName))
{
if (dirName == "")
dirName = SocketApp.FileDirectory;
else
dirName = Path.Combine(SocketApp.FileDirectory, dirName);
if (Directory.Exists(dirName))
{
string[] files = Directory.GetFiles(dirName);
_outgoingDataAssembler.AddSuccess();
Int64 fileSize = 0;
for (int i = 0; i < files.Length; i++)
{
FileInfo fileInfo = new FileInfo(files[i]);
fileSize = fileInfo.Length;
_outgoingDataAssembler.AddValue(ProtocolKey.Item, fileInfo.Name + ProtocolKey.TextSeperator + fileSize.ToString());
}
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.DirNotExist, "");
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");
return DoSendResult();
}
///
/// 说明:删除文件
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// true if XXXX, false otherwise.
public bool DoDeleteFile()
{
string dirName = "";
if (_incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName))
{
if (dirName == "")
dirName = SocketApp.FileDirectory;
else
dirName = Path.Combine(SocketApp.FileDirectory, dirName);
string fileName = "";
if (Directory.Exists(dirName))
{
try
{
List files = _incomingDataParser.GetValue(ProtocolKey.Item);
for (int i = 0; i < files.Count; i++)
{
fileName = Path.Combine(dirName, files[i]);
File.Delete(fileName);
}
_outgoingDataAssembler.AddSuccess();
}
catch (Exception E)
{
_outgoingDataAssembler.AddFailure(ProtocolCode.DeleteFileFailed, E.Message);
}
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.DirNotExist, "");
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");
return DoSendResult();
}
///
/// 说明:上传文件
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// true if XXXX, false otherwise.
public bool DoUpload()
{
string dirName = string.Empty;
string fileName = string.Empty;
long fileSize = 0;
if (_incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName) &
_incomingDataParser.GetValue(ProtocolKey.FileName, ref fileName) &
_incomingDataParser.GetValue(ProtocolKey.FileSize,ref fileSize))
{
if (string.IsNullOrWhiteSpace(dirName))
dirName = SocketApp.FileDirectory;
else
dirName = Path.Combine(SocketApp.FileDirectory, dirName);
fileName = Path.Combine(dirName, fileName);
Program.Logger.Info("Start upload file: " + fileName);
if (_fileStream != null) //关闭上次传输的文件
{
_fileStream.Close();
_fileStream = null;
_fileName = string.Empty;
}
if (File.Exists(fileName))
{
// 检测文件是否正在使用中.
if (!CheckFileInUse(fileName))
{
// 检查上传文件服务器是否存在.存在则重命名之前文件
bool isRename = CheckFileInExistAndRename(fileName, fileSize);
if (isRename)
{
_fileName = fileName;
_outgoingDataAssembler.AddSuccess();
_outgoingDataAssembler.AddValue(ProtocolKey.FileSize, 0);
}
else
{
_fileName = fileName;
_fileStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);
_fileStream.Position = _fileStream.Length; // 文件移到末尾
_outgoingDataAssembler.AddSuccess();
_outgoingDataAssembler.AddValue(ProtocolKey.FileSize,_fileStream.Length);
}
}
else
{
_outgoingDataAssembler.AddFailure(ProtocolCode.FileIsInUse, "");
Program.Logger.Error("Start upload file error, file is in use: " + fileName);
}
}
else
{
_fileName = fileName;
_fileStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
_fileStream.Position = _fileStream.Length; //文件移到末尾
_outgoingDataAssembler.AddSuccess();
_outgoingDataAssembler.AddValue(ProtocolKey.FileSize, _fileStream.Length);
}
}
else
_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");
return DoSendResult();
}
///
/// 说明:写入文件内容
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The buffer.
/// The offset.
/// The count.
/// true if XXXX, false otherwise.
public bool DoData(byte[] buffer, int offset, int count)
{
if (_fileStream == null)
{
_outgoingDataAssembler.AddFailure(ProtocolCode.NotOpenFile, "");
return false;
}
else
{
_fileStream.Write(buffer, offset, count);
return true;
//_outgoingDataAssembler.AddSuccess();
//_outgoingDataAssembler.AddValue(ProtocolKey.Count, count); //返回读取个数
}
//return DoSendResult(); //接收数据不发回响应
}
///
/// 说明:完成
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// true if XXXX, false otherwise.
public bool DoEof()
{
if (_fileStream == null)
_outgoingDataAssembler.AddFailure(ProtocolCode.NotOpenFile, "");
else
{
Program.Logger.Info("End upload file: " + _fileName);
_fileStream.Close();
_fileStream = null;
_fileName = "";
_outgoingDataAssembler.AddSuccess();
}
return DoSendResult();
}
///
/// 说明:检测文件是否正在使用中,如果正在使用中则检测是否被上传协议占用,如果占用则关闭,真表示正在使用中,并没有关闭
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// Name of the file.
/// true if XXXX, false otherwise.
public bool CheckFileInUse(string fileName)
{
if (BasicFunc.IsFileInUse(fileName))
{
bool result = true;
lock (_asyncSocketServer.UploadSocketProtocolMgr)
{
UploadSocketProtocol uploadSocketProtocol = null;
for (int i = 0; i < _asyncSocketServer.UploadSocketProtocolMgr.Count(); i++)
{
uploadSocketProtocol = _asyncSocketServer.UploadSocketProtocolMgr.ElementAt(i);
if (fileName.Equals(uploadSocketProtocol.FileName, StringComparison.CurrentCultureIgnoreCase))
{
lock (uploadSocketProtocol.AsyncSocketUserToken) //AsyncSocketUserToken有多个
{
_asyncSocketServer.CloseClientSocket(uploadSocketProtocol.AsyncSocketUserToken);
}
result = false;
}
}
}
return result;
}
else
return false;
}
///
/// 说明:检查服务器是否存在相同文件名,存在则判断是断点续传还是重新上传新文件,重新上传文件则重命名之前文件.
/// 创建人:龚宇超
/// 创建日期:2018-01-25
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// 完整路径的文件名
/// true if XXXX, false otherwise.
public bool CheckFileInExistAndRename(string fileName, long fileSize)
{
if (string.IsNullOrEmpty(fileName)) return false;
FileStream fileStream = null;
try
{
if (File.Exists(fileName))
{
fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
if (fileStream.Length == fileSize)
{
fileStream.Close();
// 已上传完成,则重命名服务器旧文件
FileInfo fileInfo = new FileInfo(fileName);
fileInfo.MoveTo(fileName.Replace(fileInfo.Extension, "_") + BasicFunc.GetCurrentTimeUnix() + fileInfo.Extension);
return true;
}
else
{
}
}
}
catch (Exception)
{
}
finally
{
if (fileStream != null) fileStream.Close();
}
return false;
}
///
/// 说明:关闭连接
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
public override void Close()
{
base.Close();
_fileName = "";
if (_fileStream != null)
{
_fileStream.Close();
_fileStream = null;
}
lock (_asyncSocketServer.UploadSocketProtocolMgr)
{
_asyncSocketServer.UploadSocketProtocolMgr.Remove(this);
}
}
///
/// 说明:处理分完包的数据,子类从这个方法继承
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The buffer.
/// The offset.
/// The count.
/// true if XXXX, false otherwise.
public override bool ProcessCommand(byte[] buffer, int offset, int count)
{
UploadSocketCommand command = StrToCommand(_incomingDataParser.Command);
_outgoingDataAssembler.Clear();
_outgoingDataAssembler.AddResponse();
_outgoingDataAssembler.AddCommand(_incomingDataParser.Command);
if (!CheckLogined(command)) //检测登录
{
_outgoingDataAssembler.AddFailure(ProtocolCode.UserHasLogined, "");
return DoSendResult();
}
if (command == UploadSocketCommand.Login)
return DoLogin();
else if (command == UploadSocketCommand.Active)
return DoActive();
else if (command == UploadSocketCommand.Dir)
return DoDir();
else if (command == UploadSocketCommand.CreateDir)
return DoCreateDir();
else if (command == UploadSocketCommand.DeleteDir)
return DoDeleteDir();
else if (command == UploadSocketCommand.FileList)
return DoFileList();
else if (command == UploadSocketCommand.DeleteFile)
return DoDeleteFile();
else if (command == UploadSocketCommand.Upload)
return DoUpload();
else if (command == UploadSocketCommand.Data)
return DoData(buffer, offset, count);
else if (command == UploadSocketCommand.Eof)
return DoEof();
else
{
Program.Logger.Error("Unknow command: " + _incomingDataParser.Command);
return false;
}
}
///
/// 说明:传入标记转换为对应上传标记
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The command.
/// UploadSocketCommand.
public UploadSocketCommand StrToCommand(string command)
{
if (command.Equals(ProtocolKey.Active, StringComparison.CurrentCultureIgnoreCase))
return UploadSocketCommand.Active;
else if (command.Equals(ProtocolKey.Login, StringComparison.CurrentCultureIgnoreCase))
return UploadSocketCommand.Login;
else if (command.Equals(ProtocolKey.Dir, StringComparison.CurrentCultureIgnoreCase))
return UploadSocketCommand.Dir;
else if (command.Equals(ProtocolKey.CreateDir, StringComparison.CurrentCultureIgnoreCase))
return UploadSocketCommand.CreateDir;
else if (command.Equals(ProtocolKey.DeleteDir, StringComparison.CurrentCultureIgnoreCase))
return UploadSocketCommand.DeleteDir;
else if (command.Equals(ProtocolKey.FileList, StringComparison.CurrentCultureIgnoreCase))
return UploadSocketCommand.FileList;
else if (command.Equals(ProtocolKey.DeleteFile, StringComparison.CurrentCultureIgnoreCase))
return UploadSocketCommand.DeleteFile;
else if (command.Equals(ProtocolKey.Upload, StringComparison.CurrentCultureIgnoreCase))
return UploadSocketCommand.Upload;
else if (command.Equals(ProtocolKey.Data, StringComparison.CurrentCultureIgnoreCase))
return UploadSocketCommand.Data;
else if (command.Equals(ProtocolKey.Eof, StringComparison.CurrentCultureIgnoreCase))
return UploadSocketCommand.Eof;
else
return UploadSocketCommand.None;
}
}
///
/// 上传文件管理类
///
public class UploadSocketProtocolMgr : Object
{
private List _list;
public UploadSocketProtocolMgr()
{
_list = new List();
}
///
/// 说明:上传文件总数
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// System.Int32.
public int Count()
{
return _list.Count;
}
///
/// 说明:获取指定UploadSocketProtocol
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The index.
/// UploadSocketProtocol.
public UploadSocketProtocol ElementAt(int index)
{
return _list.ElementAt(index);
}
///
/// 说明:添加文件
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The value.
public void Add(UploadSocketProtocol value)
{
_list.Add(value);
}
///
/// 说明:移除文件
/// 创建人:龚宇超
/// 创建日期:2018-01-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
/// The value.
public void Remove(UploadSocketProtocol value)
{
_list.Remove(value);
}
}
}