三个项目:服务端XJFtpServer,客户端XJFtpServerClient,公共程序集XJFtpServerLib
先是公共程序集:
public class FtpServerDefine
{
public const int LISTEN_PORT = 5000;
public const int MESSAGE_LENGTH=419;
}
public enum MsgCommand
{
None,
Login,
Exit,
List,
Upload,
Download,
Msg,
DirInfo,
File,
Close
}
public enum MsgSendState
{
None,
Single,
Start,
Sending,
End
}
public enum MsgType
{
None,
Text,
Class,
File
}
[Serializable]
public class Message
{
public MsgCommand Command;
public MsgType Type;
public MsgSendState SendState;
public int DataLength;
public Message()
{
Command = MsgCommand.None;
Type = MsgType.None;
SendState = MsgSendState.None;
DataLength = 0;
}
}
[Serializable]
public class UserInfo
{
public string Name;
public string Password;
public UserInfo()
{
Name = string.Empty;
Password = string.Empty;
}
}
[Serializable]
public class PathInfo
{
public string Path;
public PathInfo()
{
Path = string.Empty;
}
}
[Serializable]
public class DirectoryInfo
{
public string Name;
public string FullPath;
public long Size;
public DateTime CreateTime;
public DateTime LastAccessTime;
public List<string> SubDirectory;
public List<string> Files;
public DirectoryInfo()
{
SubDirectory = new List<string>();
Files = new List<string>();
}
public override string ToString()
{
string str = string.Empty;
str += string.Format("Name:{0}\tFullPath:{1}\tSize:{2}\tCreateTime:{3}\tLastAccessTime:{4}"
, Name
, FullPath
, Size
, CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
, LastAccessTime.ToString("yyyy-MM-dd HH:mm:ss"));
return str;
}
}
[Serializable]
public class FileInfo
{
public string Name;
public string FullName;
public long Size;
public DateTime CreateTime;
public DateTime LastAccessTime;
public FileInfo()
{
}
public override string ToString()
{
return string.Format("Name:{0}\tFullName:{1}\tSize:{2}\tCreateTime:{3}\tLastUpdateTime:{4}"
, Name
, FullName
, Size
, CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
, LastAccessTime.ToString("yyyy-MM-dd HH:mm:ss"));
}
}
[Serializable]
public class CloseInfo
{
/// <summary>
/// Close type
/// 0 Unkown close request
/// 1 Server close request
/// 2 Client close request
/// </summary>
public int Type;
public string Message;
public CloseInfo()
{
Type = 0;
Message = string.Empty;
}
}
public class Utils
{
public static byte[] Serialize<T>(T obj)
{
try
{
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, obj);
stream.Position = 0;
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Flush();
stream.Close();
return buffer;
}
catch (Exception ex)
{
throw new Exception(string.Format("Serialize fail.\r\n{0}", ex.Message));
}
}
public static T Deserialize<T>(T obj, byte[] data)
{
try
{
obj = default(T);
IFormatter formatter = new BinaryFormatter();
byte[] buffer = data;
MemoryStream stream = new MemoryStream(buffer);
stream.Seek(0, SeekOrigin.Begin);
obj = (T)formatter.Deserialize(stream);
stream.Flush();
stream.Close();
}
catch (Exception ex)
{
throw new Exception(string.Format("Deserialize fail.\r\n{0}", ex.Message));
}
return obj;
}
}
public interface IFtpServer
{
event Action<string> Debug;
int Port { get; set; }
bool IsRunning { get; }
string RootDir { get; set; }
bool Start();
bool Start(int port);
bool Stop();
void Dispose();
}
public interface IFtpSession
{
event Action<string, string> Debug;
event Action<string> Disconnected;
string RootDir { get; set; }
string CurrentDir { get; set; }
string Client { get; set; }
bool Start();
bool Close();
void Dispose();
}
public interface IFtpClient:IDisposable
{
event Action<string, string> Debug;
event Action<string, Message, byte[]> MessageReceived;
string Host { get; set; }
int Port { get; set; }
bool Connect();
bool Connect(string host, int port);
bool Close();
bool Send(Message message, int length, byte[] data);
void Dispose();
}
服务端:
class FtpServer : IFtpServer
{
private TcpListener mFtpListener;
private List<FtpSession> mFtpSessions;
private int mCheckSessionInterval;
private Timer mCheckActiveTimer;
private int mListenPort;
private bool mIsRunning;
private string mRootDir;
public FtpServer()
{
mFtpSessions = new List<FtpSession>();
mCheckSessionInterval = Common.CHECK_CLIENT_INTEVAL;
mListenPort = FtpServerDefine.LISTEN_PORT;
mIsRunning = false;
mRootDir = AppDomain.CurrentDomain.BaseDirectory;
}
private void SubAcceptClient(IAsyncResult result)
{
try
{
TcpListener listener = result.AsyncState as TcpListener;
Socket socketClient = listener.EndAcceptSocket(result);
SubDebug(string.Format("New client connected.\tClient:{0}", socketClient.RemoteEndPoint));
FtpSession session = new FtpSession(socketClient);
session.Debug += new Action<string, string>(session_Debug);
session.Disconnected += new Action<string>(session_Disconnected);
session.RootDir = mRootDir;
mFtpSessions.Add(session);
session.Start();
listener.BeginAcceptSocket(SubAcceptClient, listener);
}
catch (Exception ex)
{
SubDebug(string.Format("Accept client fail.\tAccept client breaked."));
mIsRunning = false;
}
}
void session_Disconnected(string client)
{
try
{
SubDebug(string.Format("Session:{0} disconnected.", client));
FtpSession session = mFtpSessions.Where(s => s.Client == client).First();
mFtpSessions.Remove(session);
SubDebug(string.Format("Session:{0} has removed.", client));
session.Dispose();
}
catch (Exception ex)
{
SubDebug(string.Format("Remove session fail.\r\n{0}", ex.ToString()));
}
}
void session_Debug(string client, string msg)
{
SubDebug(string.Format("Session:{0}\t{1}", client, msg));
}
void mCheckActiveTimer_Elapsed(object sender, ElapsedEventArgs e)
{
SubDebug(string.Format("Check online client.\tCount:{0}", mFtpSessions.Count));
try
{
for (int i = mFtpSessions.Count - 1; i >= 0; i--)
{
FtpSession session = mFtpSessions[i];
SubDebug(string.Format("Online client:{0}", session.Client));
if (session.LastActiveTime.AddSeconds(20) < DateTime.Now)
{
mFtpSessions.Remove(session);
SubDebug(string.Format("Session:{0} has removed.", session.Client));
session.Close();
}
}
}
catch { }
}
private void SubDebug(string msg)
{
if (Debug != null)
{
Debug(msg);
}
}
#region IFtpServer 成员
public event Action<string> Debug;
public int Port
{
get { return mListenPort; }
set { mListenPort = value; }
}
public bool IsRunning
{
get { return mIsRunning; }
}
public string RootDir
{
get
{
return mRootDir;
}
set
{
mRootDir = value;
}
}
public bool Start()
{
try
{
SubDebug(string.Format("Ftp server starting..."));
if (mFtpListener != null)
{
try
{
mFtpListener.Stop();
mFtpListener = null;
}
catch { }
}
mFtpListener = new TcpListener(IPAddress.Any, mListenPort);
mFtpListener.Start();
mIsRunning = true;
SubDebug(string.Format("Listener started.\tLocal endpoint:{0}", mFtpListener.LocalEndpoint));
mFtpListener.BeginAcceptSocket(new AsyncCallback(SubAcceptClient), mFtpListener);
mCheckActiveTimer = new Timer(mCheckSessionInterval * 1000);
mCheckActiveTimer.Elapsed += new ElapsedEventHandler(mCheckActiveTimer_Elapsed);
mCheckActiveTimer.Start();
SubDebug(string.Format("Check active timer started."));
SubDebug(string.Format("Ftp Server started.\tRootDir:{0}", mRootDir));
return true;
}
catch (Exception ex)
{
SubDebug(string.Format("Ftp server start fail.\r\n{0}", ex.ToString()));
return false;
}
}
public bool Start(int port)
{
mListenPort = port;
return Start();
}
public bool Stop()
{
Dispose();
SubDebug(string.Format("Ftp server stopped."));
return true;
}
public void Dispose()
{
if (mFtpSessions != null)
{
foreach (FtpSession session in mFtpSessions)
{
session.Dispose();
}
mFtpSessions.Clear();
SubDebug(string.Format("All session removed."));
}
if (mFtpListener != null)
{
try
{
mFtpListener.Stop();
mFtpListener = null;
SubDebug(string.Format("Ftp Listener stopped."));
}
catch { }
}
if (mCheckActiveTimer != null)
{
try
{
mCheckActiveTimer.Stop();
SubDebug(string.Format("Check active timer stopped."));
}
catch { }
}
}
#endregion
}
class FtpSession : IFtpSession
{
private string mClient;
private Socket mSocket;
private bool mIsLogined;
private string mRootDir;
private string mCurrentDir;
private byte[] mMsgBuffer;
private byte[] mDataBuffer;
private int mMsgLength;
private DateTime mLastActiveTime;
public DateTime LastActiveTime
{
get { return mLastActiveTime; }
}
public FtpSession(Socket socket)
{
mSocket = socket;
mClient = mSocket.RemoteEndPoint.ToString();
mIsLogined = false;
mRootDir = AppDomain.CurrentDomain.BaseDirectory;
mCurrentDir = string.Empty;
mMsgLength = FtpServerDefine.MESSAGE_LENGTH;
mMsgBuffer = new byte[mMsgLength];
mLastActiveTime = DateTime.Now;
}
private void SubReceiveMessage(IAsyncResult result)
{
mLastActiveTime = DateTime.Now;
int iReceiveLength = 0;
Socket socket = result.AsyncState as Socket;
try
{
iReceiveLength = socket.EndReceive(result);
}
catch (Exception ex)
{
SocketException sex = ex as SocketException;
if (sex != null)
{
SubDebug(string.Format("End receive message fail.\tClient disconected.\tReceive message break"));
SubDisconnected();
}
else
{
SubDebug(string.Format("End receive message fail.\tReceive message break."));
}
return;
}
Message message = new Message();
int dataLength = 0;
if (iReceiveLength == mMsgLength)
{
try
{
message = Utils.Deserialize<Message>(message, mMsgBuffer);
dataLength = message.DataLength;
mDataBuffer = new byte[dataLength];
}
catch (Exception ex)
{
SubDebug(string.Format("Receive message fail.\r\n{0}", ex.ToString()));
}
}
else
{
SubDebug(string.Format("Receive message length invalid.\tLength:{0}\tReceive message break.", iReceiveLength));
}
try
{
if (dataLength > 0)
{
socket.BeginReceive(mDataBuffer, 0, dataLength, SocketFlags.None, new AsyncCallback(SubReceiveData), message);
}
else
{
socket.BeginReceive(mMsgBuffer, 0, mMsgLength, SocketFlags.None, new AsyncCallback(SubReceiveMessage), socket);
}
}
catch (Exception ex)
{
SocketException sex = ex as SocketException;
if (sex != null)
{
SubDebug(string.Format("Begin receive fail.\tClient disconnected."));
SubDisconnected();
}
else
{
SubDebug(string.Format("Begin receive fail.\tReceive message break."));
}
}
}
private void SubReceiveData(IAsyncResult result)
{
int iReceiveLength = 0;
Socket socket;
Message message;
try
{
socket = mSocket;
message = result.AsyncState as Message;
iReceiveLength = socket.EndReceive(result);
}
catch (Exception ex)
{
SocketException sex = ex as SocketException;
if (sex != null)
{
SubDebug(string.Format("End receive data fail.\tClient disconected.\tReceive data break"));
SubDisconnected();
}
else
{
SubDebug(string.Format("End receive data fail.\tReceive data break."));
}
return;
}
if (iReceiveLength == message.DataLength)
{
switch (message.Command)
{
case MsgCommand.Login:
DealLogin(message, mDataBuffer);
break;
case MsgCommand.List:
DealList(message, mDataBuffer);
break;
case MsgCommand.Download:
DealDowloadCommand(mDataBuffer);
break;
case MsgCommand.Close:
DealCloseCommand(message, mDataBuffer);
break;
default:
SubDebug(string.Format("Invalid command.\tCommand:{0}", message.Command));
break;
}
}
else
{
SubDebug(string.Format("Receive data length invalid.\tLength:{0}\tNeed:{1}\tReceive data breaked.", iReceiveLength, message.DataLength));
}
try
{
socket.BeginReceive(mMsgBuffer, 0, mMsgLength, SocketFlags.None, new AsyncCallback(SubReceiveMessage), socket);
}
catch (Exception ex)
{
SocketException sex = ex as SocketException;
if (sex != null)
{
SubDebug(string.Format("Begin receive fail.\tClient disconnected."));
SubDisconnected();
}
else
{
SubDebug(string.Format("Begin receive fail.\tReceive message break."));
}
}
}
private bool SendMessage(Message message, int length, byte[] data)
{
if (mSocket == null && !mSocket.Connected)
{
SubDebug(string.Format("Send message fail.\tMsg:{0}\tSocket is null or not connected.", message.Command));
return false;
}
try
{
message.DataLength = length;
byte[] bMsg = Utils.Serialize<Message>(message);
mSocket.Send(bMsg);
mSocket.Send(data, length, SocketFlags.None);
mLastActiveTime = DateTime.Now;
}
catch (Exception ex)
{
//SubDebug(string.Format("Send message fail.\tMsg:{0}\r\n{1}", message.Command, ex.ToString()));
return false;
}
return true;
}
private bool DealLogin(Message message, byte[] data)
{
SubDebug(string.Format("Deal login command."));
try
{
UserInfo userInfo = new UserInfo();
userInfo = Utils.Deserialize<UserInfo>(userInfo, data);
Message retMessage = new Message();
retMessage.Command = MsgCommand.Msg;
retMessage.Type = MsgType.Text;
byte[] msg;
if (userInfo.Name != "administrator")
{
msg = Encoding.UTF8.GetBytes("User not exist.");
SendMessage(retMessage, msg.Length, msg);
return false;
}
if (userInfo.Password != "voicecyber")
{
msg = Encoding.UTF8.GetBytes("Password error.");
SendMessage(retMessage, msg.Length, msg);
return false;
}
mIsLogined = true;
msg = Encoding.UTF8.GetBytes(string.Format("{0}\t Logined", userInfo.Name));
SendMessage(retMessage, msg.Length, msg);
SubDebug(string.Format("{0} Logined.", userInfo.Name));
return true;
}
catch (Exception ex)
{
SubDebug(string.Format("Deal Login command fail.\r\n{0}", ex.ToString()));
return false;
}
}
private bool DealList(Message message, byte[] data)
{
SubDebug(string.Format("Deal list command."));
try
{
Message retMessage = new Message();
retMessage.Command = MsgCommand.Msg;
retMessage.Type = MsgType.Text;
byte[] retData;
if (!mIsLogined)
{
retData = Encoding.UTF8.GetBytes("Not login.");
SendMessage(retMessage, retData.Length, retData);
return false;
}
PathInfo pathInfo = new PathInfo();
pathInfo = Utils.Deserialize<PathInfo>(pathInfo, data);
string path = pathInfo.Path;
path = System.IO.Path.Combine(mRootDir, mCurrentDir, path);
if (!System.IO.Directory.Exists(path))
{
retData = Encoding.UTF8.GetBytes(string.Format("Directory not exist.\t{0}", path));
SendMessage(retMessage, retData.Length, retData);
return false;
}
DirectoryInfo dirInfo = GetDirInfo(path);
retMessage.Command = MsgCommand.DirInfo;
retMessage.Type = MsgType.Class;
retData = Utils.Serialize<DirectoryInfo>(dirInfo);
SendMessage(retMessage, retData.Length, retData);
return true;
}
catch (Exception ex)
{
SubDebug(string.Format("Deal List command fail.\r\n{0}", ex.ToString()));
return false;
}
}
private bool DealDowloadCommand(byte[] data)
{
SubDebug(string.Format("Deal Download command."));
try
{
PathInfo pathInfo = new PathInfo();
pathInfo = Utils.Deserialize<PathInfo>(pathInfo, data);
Message retMessage = new Message();
retMessage.Command = MsgCommand.Msg;
retMessage.Type = MsgType.Text;
byte[] msg;
string filePath = System.IO.Path.Combine(mRootDir, pathInfo.Path);
if (!System.IO.File.Exists(filePath))
{
msg = Encoding.UTF8.GetBytes(string.Format("File not exist.\t{0}", filePath));
SendMessage(retMessage, msg.Length, msg);
return false;
}
using (System.IO.FileStream fs = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
long iLength = fs.Length;
byte[] buffer = new byte[1024];
int iRead = 0;
while (true)
{
iRead = fs.Read(buffer, 0, 1024);
if (iRead <= 0)
{
break;
}
if (iRead < 1024)
{
retMessage.Command = MsgCommand.File;
retMessage.Type = MsgType.File;
retMessage.SendState = MsgSendState.End;
SendMessage(retMessage, iRead, buffer);
break;
}
retMessage.Command = MsgCommand.File;
retMessage.Type = MsgType.File;
retMessage.SendState = MsgSendState.Sending;
SendMessage(retMessage, 1024, buffer);
}
}
return true;
}
catch (Exception ex)
{
SubDebug(string.Format("Deal Download command fail.\r\n{0}", ex.ToString()));
return false;
}
}
private bool DealCloseCommand(Message message, byte[] data)
{
SubDebug(string.Format("Deal Close command."));
try
{
CloseInfo closeInfo = new CloseInfo();
closeInfo = Utils.Deserialize<CloseInfo>(closeInfo, data);
SubDebug(string.Format("Receive close command.\tType:{0}\tMessage:{1}", closeInfo.Type, closeInfo.Message));
Close();
SubDisconnected();
return true;
}
catch (Exception ex)
{
SubDebug(string.Format("Deal Close command fail.\r\n{0}", ex.ToString()));
return false;
}
}
private DirectoryInfo GetDirInfo(string path)
{
System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(path);
DirectoryInfo diretoryInfo = new DirectoryInfo();
diretoryInfo.Name = dirInfo.Name;
diretoryInfo.FullPath = dirInfo.FullName;
//diretoryInfo.CreateTime = dirInfo.CreationTime;
//diretoryInfo.LastAccessTime = dirInfo.LastAccessTime;
diretoryInfo.Size = 0;
foreach (System.IO.DirectoryInfo subDir in dirInfo.GetDirectories())
{
DirectoryInfo subDirectory = GetDirInfo(subDir.FullName);
diretoryInfo.Size += subDirectory.Size;
//diretoryInfo.SubDirectory.Add(subDirectory);
diretoryInfo.SubDirectory.Add(subDirectory.Name);
}
foreach (System.IO.FileInfo subFile in dirInfo.GetFiles())
{
FileInfo fileInfo = new FileInfo();
fileInfo.Name = subFile.Name;
fileInfo.FullName = subFile.FullName;
fileInfo.Size = subFile.Length;
//fileInfo.CreateTime = subFile.CreationTime;
//fileInfo.LastAccessTime = subFile.LastAccessTime;
diretoryInfo.Size += fileInfo.Size;
//diretoryInfo.Files.Add(fileInfo);
diretoryInfo.Files.Add(fileInfo.Name);
}
return diretoryInfo;
}
private void SubDebug(string msg)
{
if (Debug != null)
{
Debug(mClient, msg);
}
}
private void SubDisconnected()
{
if (Disconnected != null)
{
Disconnected(mClient);
}
}
#region IFtpSession 成员
public event Action<string, string> Debug;
public event Action<string> Disconnected;
public string RootDir
{
get
{
return mRootDir;
}
set
{
mRootDir = value;
}
}
public string CurrentDir
{
get
{
return mCurrentDir;
}
set
{
mCurrentDir = value;
}
}
public string Client
{
get { return mClient; }
set { mClient = value; }
}
public bool Start()
{
if (mSocket == null || !mSocket.Connected)
{
SubDebug(string.Format("Session start fail.\tSocket is null or not connected."));
return false;
}
try
{
mSocket.BeginReceive(mMsgBuffer, 0, mMsgLength, SocketFlags.None, new AsyncCallback(SubReceiveMessage), mSocket);
}
catch (Exception ex)
{
SocketException sex = ex as SocketException;
if (sex != null)
{
SubDebug(string.Format("Begin receive fail.\tClient disconnected."));
SubDisconnected();
}
else
{
SubDebug(string.Format("Begin receive fail.\tReceive message break."));
}
return false;
}
Message message = new Message();
message.Command = MsgCommand.Msg;
message.Type = MsgType.Text;
byte[] data = Encoding.UTF8.GetBytes(string.Format("Welcome MDMSFtpServer!\tCurrent directory:{0}", mCurrentDir));
SendMessage(message, data.Length, data);
return true;
}
public bool Close()
{
if (mSocket != null && mSocket.Connected)
{
try
{
mSocket.Close();
SubDebug(string.Format("Socket closed."));
}
catch (Exception ex)
{
SubDebug(string.Format("Socket close fail.\r\n{0}", ex.ToString()));
return false;
}
}
return true;
}
public void Dispose()
{
if (mSocket != null)
{
try
{
mSocket.Close();
}
catch { }
}
}
#endregion
}
客户端:
public class FtpClient : IFtpClient
{
private string mClient;
private Socket mSocket;
private string mHost;
private int mPort;
private int mMsgLength;
private byte[] mBuffer;
private int mReceiveLength;
private bool mIsReceiveMessage;
private Message mMessage;
public FtpClient()
{
mClient = string.Empty;
mHost = string.Empty;
mPort = FtpServerDefine.LISTEN_PORT;
mMsgLength = FtpServerDefine.MESSAGE_LENGTH;
mIsReceiveMessage = true;
mMessage = new Message();
}
public FtpClient(string client)
: this()
{
mClient = client;
}
public bool Send(Message message, byte[] data)
{
return Send(message, data.Length, data);
}
private bool ConnectToServer()
{
try
{
Dispose();
mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mSocket.Connect(mHost, mPort);
if (mSocket.Connected)
{
mReceiveLength = mMsgLength;
mBuffer = new byte[mReceiveLength];
mIsReceiveMessage = true;
mSocket.BeginReceive(mBuffer, 0, mReceiveLength, SocketFlags.None, new AsyncCallback(SubReceiveMessage), mSocket);
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
SocketException sex = ex as SocketException;
if (sex != null)
{
SubDebug(string.Format("Begin receive fail.\tClient disconnected."));
}
SubDebug(string.Format("Connect to server fail.\r\n{0}", ex.ToString()));
return false;
}
}
private void SubReceiveMessage(IAsyncResult result)
{
int iReceiveLength = 0;
Socket socket = result.AsyncState as Socket;
try
{
iReceiveLength = socket.EndReceive(result);
}
catch (Exception ex)
{
SocketException sex = ex as SocketException;
if (sex != null)
{
SubDebug(string.Format("End receive message fail.\tServer disconected.\tReceive data break"));
}
else
{
SubDebug(string.Format("End receive message fail.\tReceive data break."));
}
return;
}
if (iReceiveLength == 0)
{
SubDebug(string.Format("Receive 0 bytes.\tReceive message break."));
return;
}
int index = 0;
if (iReceiveLength < mReceiveLength)
{
mReceiveLength = mReceiveLength - iReceiveLength;
index = iReceiveLength;
}
else
{
if (mIsReceiveMessage)
{
mIsReceiveMessage = false;
Message message = new Message();
message = Utils.Deserialize<Message>(message, mBuffer);
mMessage = message;
mReceiveLength = message.DataLength;
mBuffer = new byte[mReceiveLength];
}
else
{
mIsReceiveMessage = true;
SubMessageReceived(mMessage, mBuffer);
mReceiveLength = mMsgLength;
mBuffer = new byte[mReceiveLength];
}
}
try
{
socket.BeginReceive(mBuffer, index, mReceiveLength, SocketFlags.None, new AsyncCallback(SubReceiveMessage), socket);
}
catch (Exception ex)
{
SocketException sex = ex as SocketException;
if (sex != null)
{
SubDebug(string.Format("Begin receive fail.\tClient disconnected."));
}
else
{
SubDebug(string.Format("Begin receive fail.\tReceive message break."));
}
}
}
private bool SendMessage(Message message, int length, byte[] data)
{
try
{
message.DataLength = length;
byte[] bMsg = Utils.Serialize<Message>(message);
mSocket.Send(bMsg);
mSocket.Send(data, length, SocketFlags.None);
}
catch (Exception ex)
{
SubDebug(string.Format("Send message fail.\tMsg:{0}\r\n{1}", message.Command, ex.ToString()));
return false;
}
return true;
}
private void SubMessageReceived(Message message, byte[] data)
{
if (MessageReceived != null)
{
MessageReceived(mClient, message, data);
}
}
public void SubDebug(string msg)
{
if (Debug != null)
{
Debug(mClient, msg);
}
}
#region IFtpClient 成员
public event Action<string, string> Debug;
public event Action<string, Message, byte[]> MessageReceived;
public string Host
{
get { return mHost; }
set { mHost = value; }
}
public int Port
{
get { return mPort; }
set { mPort = value; }
}
public bool Connect()
{
if (!ConnectToServer())
{
return false;
}
return true;
}
public bool Connect(string host, int port)
{
mHost = host;
mPort = port;
return Connect();
}
public bool Close()
{
if (mSocket != null && mSocket.Connected)
{
try
{
mSocket.Close();
SubDebug(string.Format("Socket closed."));
}
catch (Exception ex)
{
SubDebug(string.Format("Socket close fail.\r\n{0}", ex.ToString()));
return false;
}
}
return true;
}
public bool Send(Message message, int length, byte[] data)
{
return SendMessage(message, length, data);
}
public void Dispose()
{
if (mSocket != null && mSocket.Connected)
{
try
{
mSocket.Close();
mSocket = null;
}
catch { }
}
}
#endregion
}
文件操作:
public class FileOperator : IDisposable
{
public event Action<string> Debug;
private string mPath;
private FileStream mFileStream;
public FileOperator()
{
}
public bool Create(string path)
{
if (!Path.IsPathRooted(path))
{
mPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
}
else
{
mPath = path;
}
try
{
if (File.Exists(mPath))
{
File.Delete(mPath);
}
mFileStream = new FileStream(mPath, FileMode.OpenOrCreate, FileAccess.Write);
return true;
}
catch (Exception ex)
{
SubDebug(string.Format("Create file fail.\r\n{0}", ex.ToString()));
return false;
}
}
public bool WriteData(int length, byte[] data)
{
try
{
if (mFileStream == null)
{
mFileStream = new FileStream(mPath, FileMode.OpenOrCreate, FileAccess.Write);
}
mFileStream.Write(data, 0, length);
return true;
}
catch (Exception ex)
{
SubDebug(string.Format("Write data fail.\r\n{0}", ex.ToString()));
return false;
}
}
public bool Close()
{
try
{
if (mFileStream != null)
{
mFileStream.Close();
mFileStream = null;
}
return true;
}
catch (Exception ex)
{
SubDebug(string.Format("Write data fail.\r\n{0}", ex.ToString()));
return false;
}
}
private void SubDebug(string msg)
{
if (Debug != null)
{
Debug(msg);
}
}
#region IDisposable 成员
public void Dispose()
{
if (mFileStream != null)
{
try
{
mFileStream.Close();
mFileStream = null;
}
catch { }
}
}
#endregion
}