📄 paulsftpmodel.cs
字号:
namespace FTP.Model
{
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Net.Sockets;
using System.Collections;
using FTP.Model.DataStructures;
public class PaulsFTPModel
{
// Properties
private InterpretUnixResponse serverReponseInterpreter; // To Do: make an abstract class so we can create other intpreters
private ModelViewState ftpViewState;
private Queue messagesFromServer;
private Socket commandSocket;
private const string CRLF = "\r\n";
private const int COMMAND_BLOCK_SIZE = 512;
private const int DATA_BLOCK_SIZE = 1024;
// Delegate (used to "push" changes to the View)
public delegate void PushChangesToView (ref ModelViewState ftpViewState);
public PushChangesToView pushChangesToView;
public delegate void PullStateFromView();
public PullStateFromView pullStateFromView;
// Constructor
public PaulsFTPModel()
{
// Create instances of local objects
this.messagesFromServer = new Queue();
ftpViewState = new ModelViewState();
serverReponseInterpreter = new InterpretUnixResponse();
}
// ///////////////////////////////////////////////////
// /////////////// PUBLIC METHODS ///////////////////
// ///////////////////////////////////////////////////
// Called from the Controller
public void pushChanges()
{
ftpViewState.consoleOutput = MessagesFromServer; // Get the latest server messages
pushChangesToView(ref this.ftpViewState);
}
private string MessagesFromServer
{
get
{
string allMessages = "";
IEnumerator queueEnumerator = this.messagesFromServer.GetEnumerator();
while (queueEnumerator.MoveNext())
allMessages += queueEnumerator.Current + CRLF;
return allMessages;}
}
private byte fileDownloadPercent = 0;
public byte FileDownloadPercent
{
get
{
return this.fileDownloadPercent;
}
}
private struct commandReply
{
public int code;
public string message;
}
public void connect()
{
if (this.ftpViewState.connected) Console.WriteLine ("******* already connected");
// Destroy any old data
this.pullStateFromView(); // To get URL, port, username and password
// Create the commandSocket and connect to the server
this.commandSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint serverIPEndPoint = new IPEndPoint(IPAddress.Parse(ftpViewState.serverAddress), ftpViewState.serverPort);
this.commandSocket.Connect(serverIPEndPoint);
// Check the response
commandReply reply = this.readCommandReply();
// If all was successful:
this.ftpViewState.connected = true;
this.login();
this.commandSYST();
this.commandPWD();
this.commandTYPE("A");
this.commandLIST();
}
// FTP LOGIN USER + PASS
public void login()
{
if (!this.ftpViewState.connected) Console.WriteLine ("******* NOT connected - an error will occur");
string command = "USER " + ftpViewState.userName;
this.handleServerOutput("LOCAL> " + command);
command += CRLF;
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
commandReply reply = this.readCommandReply();
command = "PASS " + ftpViewState.password;
this.handleServerOutput("LOCAL> PASS *****");
command += CRLF;
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
reply = this.readCommandReply();
}
// FTP Command PWD
public void commandPWD ()
{
string command = "PWD";
command += CRLF;
this.handleServerOutput("LOCAL> " + command);
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
commandReply reply = this.readCommandReply();
// Interpret the reply
this.ftpViewState.CurrentServerDirectory = serverReponseInterpreter.processPWDResponse(reply.message);
this.pushChanges();
}
// FTP Command CWD
public void commandCWD ()
{
this.pullStateFromView(); // To get requested directory
string command = "CWD " + this.ftpViewState.requestedServerDirectory;
this.handleServerOutput("LOCAL> " + command);
command += CRLF;
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
commandReply reply = this.readCommandReply();
// Interpret the reply
if (reply.code == 250)
{
this.pushChanges();
this.ftpViewState.CurrentServerDirectory = this.ftpViewState.requestedServerDirectory.Substring(1);
if ((this.ftpViewState.CurrentServerDirectory) == "") this.ftpViewState.CurrentServerDirectory = "/"; //xyzzy make root dir
}
// else
// To Do: Handle error
}
// FTP Command MKD
public void commandMKD ()
{
this.pullStateFromView(); // To get requested directory
string command = "MKD " + this.ftpViewState.newServerDirectory;
this.handleServerOutput("LOCAL> " + command);
command += CRLF;
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
commandReply reply = this.readCommandReply();
this.pushChanges();
// clear the cache for the current directory and LIST
ftpViewState.flushCurrentDirectoryCache();
}
// FTP Command RMD
public void commandRMD ()
{
this.pullStateFromView(); // To get requested directory
string command = "RMD " + this.ftpViewState.deleteServerDirectory;
this.handleServerOutput("LOCAL> " + command);
command += CRLF;
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
commandReply reply = this.readCommandReply();
this.pushChanges();
// clear the cache for the current directory and LIST
ftpViewState.flushCurrentDirectoryCache();
}
// FTP Command DELE
public void commandDELE ()
{
this.pullStateFromView(); // To get requested directory
string command = "DELE " + this.ftpViewState.deleteServerFile;
this.handleServerOutput("LOCAL> " + command);
command += CRLF;
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
commandReply reply = this.readCommandReply();
this.pushChanges();
// clear the cache for the current directory and LIST
ftpViewState.flushCurrentDirectoryCache();
}
// FTP Command SYST
public void commandSYST ()
{
string command = "SYST";
this.handleServerOutput("LOCAL> " + command);
command += CRLF;
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
commandReply reply = this.readCommandReply();
// To Do: Record the server type to ViewState
this.pushChanges();
}
// FTP Command NOOP
public void commandNOOP ()
{
string command = "NOOP";
this.handleServerOutput("LOCAL> " + command);
command += CRLF;
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
commandReply reply = this.readCommandReply();
}
// FTP Command TYPE
public void commandTYPE (string pType)
{
string command = "TYPE " + pType;
this.handleServerOutput("LOCAL> " + command);
command += CRLF;
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
commandReply reply = this.readCommandReply();
}
// FTP Command LIST
public void commandLIST ()
{
this.pullStateFromView();
// Check if the data is in the Cache already
if (!ftpViewState.isCWDInCache())
{
Socket dataSocket = getDataSocket(); // open a data socket;
string command = "LIST";
this.handleServerOutput("LOCAL> " + command);
this.pushChanges();
command += CRLF;
commandSocket.Send(Encoding.ASCII.GetBytes(command), command.Length, 0);
commandReply reply = this.readCommandReply();
this.pushChanges();
if (reply.code == 150)
{
// Now read data from the dataSocket
Byte[] readBytes;
int sizeReceived;
string serverMessage = "";
do
{
readBytes = new Byte[COMMAND_BLOCK_SIZE];
sizeReceived = dataSocket.Receive(readBytes, readBytes.Length, SocketFlags.None);
serverMessage += Encoding.ASCII.GetString(readBytes, 0, sizeReceived);
}
while (sizeReceived == readBytes.Length & !serverMessage.EndsWith(CRLF)); // Go back for more if necessary
this.readCommandReply(); // Read the reply from the server
// Ensure our ServerFiles datastructure is updated with this LIST
ftpViewState.addServerLIST(serverReponseInterpreter.processLISTResponse(serverMessage));
}
// else
// Error handling
}
this.pushChanges();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -