基线 SVN r240
SVN-Revision: r240
This commit is contained in:
@@ -0,0 +1,451 @@
|
||||
/******************************
|
||||
* 说明:下载文件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
|
||||
{
|
||||
/// <summary>
|
||||
/// 下载文件Socket通讯协议
|
||||
/// </summary>
|
||||
public class DownloadSocketProtocol : BaseSocketProtocol
|
||||
{
|
||||
private bool _sendFile;
|
||||
private int _packetSize;
|
||||
private byte[] _readBuffer;
|
||||
private string _fileName;
|
||||
|
||||
private FileStream _fileStream;
|
||||
/// <summary>
|
||||
/// 文件名
|
||||
/// </summary>
|
||||
/// <value>The name of the file.</value>
|
||||
public string FileName { get { return _fileName; } }
|
||||
|
||||
public DownloadSocketProtocol(AsyncSocketServer asyncSocketServer, AsyncSocketUserToken asyncSocketUserToken)
|
||||
: base(asyncSocketServer, asyncSocketUserToken)
|
||||
{
|
||||
_socketFlag = "Download";
|
||||
_fileName = "";
|
||||
_fileStream = null;
|
||||
_sendFile = false;
|
||||
_packetSize = 64 * 1024;
|
||||
lock (_asyncSocketServer.DownloadSocketProtocolMgr)
|
||||
{
|
||||
_asyncSocketServer.DownloadSocketProtocolMgr.Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>说明:关闭</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
public override void Close()
|
||||
{
|
||||
base.Close();
|
||||
_fileName = "";
|
||||
_sendFile = false;
|
||||
if (_fileStream != null)
|
||||
{
|
||||
_fileStream.Close();
|
||||
_fileStream = null;
|
||||
}
|
||||
lock (_asyncSocketServer)
|
||||
{
|
||||
_asyncSocketServer.DownloadSocketProtocolMgr.Remove(this);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:处理分完包的数据,子类从这个方法继承</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="buffer">The buffer.</param>
|
||||
/// <param name="offset">The offset.</param>
|
||||
/// <param name="count">The count.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
public override bool ProcessCommand(byte[] buffer, int offset, int count)
|
||||
{
|
||||
DownloadSocketCommand command = StrToCommand(_incomingDataParser.Command);
|
||||
_outgoingDataAssembler.Clear();
|
||||
_outgoingDataAssembler.AddResponse();
|
||||
_outgoingDataAssembler.AddCommand(_incomingDataParser.Command);
|
||||
if (!CheckLogined(command)) //检测登录
|
||||
{
|
||||
_outgoingDataAssembler.AddFailure(ProtocolCode.UserHasLogined, "");
|
||||
return DoSendResult();
|
||||
}
|
||||
if (command == DownloadSocketCommand.Login)
|
||||
return DoLogin();
|
||||
else if (command == DownloadSocketCommand.Active)
|
||||
return DoActive();
|
||||
else if (command == DownloadSocketCommand.Dir)
|
||||
return DoDir();
|
||||
else if (command == DownloadSocketCommand.FileList)
|
||||
return DoFileList();
|
||||
else if (command == DownloadSocketCommand.Download)
|
||||
return DoDownload();
|
||||
else
|
||||
{
|
||||
Program.Logger.Error("Unknow command: " + _incomingDataParser.Command);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:字符串转换对应下载命令</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="command">The command.</param>
|
||||
/// <returns>DownloadSocketCommand.</returns>
|
||||
public DownloadSocketCommand StrToCommand(string command)
|
||||
{
|
||||
if (command.Equals(ProtocolKey.Active, StringComparison.CurrentCultureIgnoreCase))
|
||||
return DownloadSocketCommand.Active;
|
||||
else if (command.Equals(ProtocolKey.Login, StringComparison.CurrentCultureIgnoreCase))
|
||||
return DownloadSocketCommand.Login;
|
||||
else if (command.Equals(ProtocolKey.Dir, StringComparison.CurrentCultureIgnoreCase))
|
||||
return DownloadSocketCommand.Dir;
|
||||
else if (command.Equals(ProtocolKey.FileList, StringComparison.CurrentCultureIgnoreCase))
|
||||
return DownloadSocketCommand.FileList;
|
||||
else if (command.Equals(ProtocolKey.Download, StringComparison.CurrentCultureIgnoreCase))
|
||||
return DownloadSocketCommand.Download;
|
||||
else
|
||||
return DownloadSocketCommand.None;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:检查是否登录</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="command">The command.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
public bool CheckLogined(DownloadSocketCommand command)
|
||||
{
|
||||
if ((command == DownloadSocketCommand.Login) | (command == DownloadSocketCommand.Active))
|
||||
return true;
|
||||
else
|
||||
return _logined;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:获取目录</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
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();
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:获取文件列表</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
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();
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:下载文件</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
public bool DoDownload()
|
||||
{
|
||||
string dirName = string.Empty;
|
||||
string fileName = string.Empty;
|
||||
if (_incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName) &
|
||||
_incomingDataParser.GetValue(ProtocolKey.FileName, ref fileName))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(dirName))
|
||||
dirName = SocketApp.FileDirectory;
|
||||
else
|
||||
dirName = Path.Combine(SocketApp.FileDirectory, dirName);
|
||||
fileName = Path.Combine(dirName, fileName);
|
||||
Program.Logger.Info("Start download file: " + fileName);
|
||||
if (_fileStream != null) //关闭上次传输的文件
|
||||
{
|
||||
_fileStream.Close();
|
||||
_fileStream = null;
|
||||
_fileName = "";
|
||||
_sendFile = false;
|
||||
}
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
if (!CheckFileInUse(fileName)) //检测文件是否正在使用中
|
||||
{
|
||||
_fileName = fileName;
|
||||
_fileStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);
|
||||
_sendFile = true;
|
||||
|
||||
_outgoingDataAssembler.AddSuccess();
|
||||
_outgoingDataAssembler.AddValue(ProtocolKey.FileSize, _fileStream.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
_outgoingDataAssembler.AddFailure(ProtocolCode.FileIsInUse, "");
|
||||
Program.Logger.Error("Start download file error, file is in use: " + fileName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_outgoingDataAssembler.AddFailure(ProtocolCode.FileNotExist, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");
|
||||
|
||||
return DoSendResult();
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:检测文件是否正在使用中,如果正在使用中则检测是否被上传协议占用,如果占用则关闭,true表示正在使用中,并没有关闭</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="fileName">Name of the file.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
public bool CheckFileInUse(string fileName)
|
||||
{
|
||||
if (BasicFunc.IsFileInUse(fileName))
|
||||
{
|
||||
bool result = true;
|
||||
lock (_asyncSocketServer.DownloadSocketProtocolMgr)
|
||||
{
|
||||
DownloadSocketProtocol downloadSocketProtocol = null;
|
||||
for (int i = 0; i < _asyncSocketServer.DownloadSocketProtocolMgr.Count(); i++)
|
||||
{
|
||||
downloadSocketProtocol = _asyncSocketServer.DownloadSocketProtocolMgr.ElementAt(i);
|
||||
if (fileName.Equals(downloadSocketProtocol.FileName, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
lock (downloadSocketProtocol.AsyncSocketUserToken) //AsyncSocketUserToken有多个线程访问
|
||||
{
|
||||
_asyncSocketServer.CloseClientSocket(downloadSocketProtocol.AsyncSocketUserToken);
|
||||
}
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:发送数据</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
public override bool SendCallback()
|
||||
{
|
||||
bool result = base.SendCallback();
|
||||
if (_fileStream != null)
|
||||
{
|
||||
if (_sendFile) //发送文件头
|
||||
{
|
||||
_outgoingDataAssembler.Clear();
|
||||
_outgoingDataAssembler.AddResponse();
|
||||
_outgoingDataAssembler.AddCommand(ProtocolKey.SendFile);
|
||||
_outgoingDataAssembler.AddSuccess();
|
||||
_outgoingDataAssembler.AddValue(ProtocolKey.FileSize, _fileStream.Length - _fileStream.Position);
|
||||
result = DoSendResult();
|
||||
_sendFile = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_fileStream.Position < _fileStream.Length) //发送具体数据
|
||||
{
|
||||
_outgoingDataAssembler.Clear();
|
||||
_outgoingDataAssembler.AddResponse();
|
||||
_outgoingDataAssembler.AddCommand(ProtocolKey.Data);
|
||||
_outgoingDataAssembler.AddSuccess();
|
||||
if (_readBuffer == null)
|
||||
_readBuffer = new byte[_packetSize];
|
||||
else if (_readBuffer.Length < _packetSize) //避免多次申请内存
|
||||
_readBuffer = new byte[_packetSize];
|
||||
int count = _fileStream.Read(_readBuffer, 0, _packetSize);
|
||||
result = DoSendResult(_readBuffer, 0, count);
|
||||
}
|
||||
else //发送完成
|
||||
{
|
||||
Program.Logger.Info("End download file: " + _fileName);
|
||||
_fileStream.Close();
|
||||
_fileStream = null;
|
||||
_fileName = "";
|
||||
_sendFile = false;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载文件管理类
|
||||
/// </summary>
|
||||
public class DownloadSocketProtocolMgr : Object
|
||||
{
|
||||
private List<DownloadSocketProtocol> _list;
|
||||
public DownloadSocketProtocolMgr()
|
||||
{
|
||||
_list = new List<DownloadSocketProtocol>();
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:获取下载个数</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Count()
|
||||
{
|
||||
return _list.Count;
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:根据index返回指定DownloadSocketProtocol</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <returns>DownloadSocketProtocol.</returns>
|
||||
public DownloadSocketProtocol ElementAt(int index)
|
||||
{
|
||||
return _list.ElementAt(index);
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:添加</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
public void Add(DownloadSocketProtocol value)
|
||||
{
|
||||
_list.Add(value);
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>说明:移除</para>
|
||||
/// <para>创建人:龚宇超</para>
|
||||
/// <para>创建日期:2018-01-24 </para>
|
||||
/// <para>修改人:</para>
|
||||
/// <para>修改日期:</para>
|
||||
/// <para>修改备注:</para>
|
||||
/// <para>版本:1.0</para>
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
public void Remove(DownloadSocketProtocol value)
|
||||
{
|
||||
_list.Remove(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user