/****************************** * 说明:上传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); } } }