public FTPClient(IPAddress serverIP, int localControlPort, string user, string password, Action <string> ConsoleLogDelegate) { controlClient = new TcpClient(); dataClient = new TcpClient(); ConsoleLogEvent += ConsoleLogDelegate; controlPort = localControlPort; dataPort = controlPort + 1; try { controlClient.Connect(serverIP, MyFTPHelper.ftpControlPort); controlStream = controlClient.GetStream(); FTPCommand userCommand = new FTPCommand("USER", new string[] { user }); if (!SendMessageToServerAndWaitReply(userCommand.ToString() + MyFTPHelper.FTPNewLine)) { return; } FTPCommand passwordCommand = new FTPCommand("PASS", new string[] { password }); if (!SendMessageToServerAndWaitReply(passwordCommand.ToString() + MyFTPHelper.FTPNewLine)) { return; } } catch (Exception exc) { throw exc; } }
public async Task <FTPResponse> SendCommandAsync(FTPCommand command, CancellationToken token = default(CancellationToken)) { return(await SendCommandAsync(new FTPCommandEnvelope { FtpCommand = command }, token)); }
public void SendCommand(FTPCommand command, params object[] args) { string cmd = InterpretCommand(command, args); print(">> " + cmd); controlConnectionSocket.Send(ToASCII(cmd)); }
public static FTPCommand?ReadNextCommand(NetworkStream stream) { if (CachedCommands.Count > 0) { return(CachedCommands.Dequeue()); } string streamstring = null; try { streamstring = MyFTPHelper.ReadFromNetStream(stream); } catch (Exception exc) { throw exc; } string[] messages = streamstring.Split(new string[] { MyFTPHelper.FTPNewLine }, StringSplitOptions.RemoveEmptyEntries); Array.ForEach(messages, (m) => CachedCommands.Enqueue(FTPCommand.String2Command(m))); if (CachedCommands.Count > 0) { return(CachedCommands.Dequeue()); } else { return(null); } }
public void SendCommand(FTPCommand command, bool shouldPrint, params object[] args) { string cmd = InterpretCommand(command, args); if (shouldPrint) { print(">> " + cmd); } controlConnectionSocket.Send(ToASCII(cmd)); }
public static string Command2String(FTPCommand command) { String s = command.controlCommand; if (command.parameters != null) { Array.ForEach(command.parameters, (p) => s += " " + p); } return(s); }
public static string InterpretCommand(FTPCommand cmd, params object[] args) { switch (cmd) { case FTPCommand.ChangeToParent: return("CDUP"); case FTPCommand.StructureMount: return("SMNT"); case FTPCommand.StoreUnique: return("STOU"); case FTPCommand.RemoveDirectory: return("RMD"); case FTPCommand.MakeDirectory: return("MKD"); case FTPCommand.PrintDirectory: return("PWD"); case FTPCommand.ChangeDirectory: return(string.Format("CWD {0}", args)); case FTPCommand.System: return("SYST"); case FTPCommand.User: return(string.Format("USER {0}", args)); case FTPCommand.ListFiles: return("NLST"); case FTPCommand.SetPortActive: return(string.Format("PORT {0}", args)); case FTPCommand.SetPortPassive: return(string.Format("PASV {0}", args)); case FTPCommand.RetrieveFile: return(string.Format("RETR {0}", args)); case FTPCommand.SetTransferMode: return(string.Format("MODE {0}", args)); case FTPCommand.SetTransferType: return(string.Format("TYPE {0}", args)); case FTPCommand.AppendFile: return(string.Format("APPE {0}", args)); case FTPCommand.Put: return(string.Format("STOR {0}", args)); case FTPCommand.Disconnect: return("QUIT"); default: throw new Exception("Can not interpret this command"); } }
public static FTPCommand String2Command(string s) { string[] tokens = s.Split(' '); FTPCommand cmd = new FTPCommand(); List <string> parameters = new List <string>(); foreach (var token in tokens) { if (cmd.controlCommand == null) { cmd.controlCommand = token; } else { parameters.Add(token); } } cmd.parameters = parameters.ToArray(); return(cmd); }
/// <summary> /// Opens a filestream to the given filename /// </summary> /// <param name="fileName"></param> /// <param name="command"></param> /// <returns></returns> private async Task <Stream> OpenFileStreamAsync(string fileName, FTPCommand command) { EnsureLoggedIn(); Logger?.LogDebug($"[FTPClient] Opening filestream for {fileName}, {command}"); dataStream = await ConnectDataStreamAsync(); var retrResponse = await ControlStream.SendCommandAsync(new FTPCommandEnvelope { FTPCommand = command, Data = fileName }); if ((retrResponse.FTPStatusCode != FTPStatusCode.DATAALREADYOPEN) && (retrResponse.FTPStatusCode != FTPStatusCode.OPENINGDATA) && (retrResponse.FTPStatusCode != FTPStatusCode.CLOSINGDATA)) { throw new FTPException(retrResponse.ResponseMessage); } return(dataStream); }
public void DownLoadFile(string filename, int size) { FTPCommand portCommand = new FTPCommand("PORT", new string[] { controlPort.ToString() }); if (!SendMessageToServerAndWaitReply(portCommand.ToString() + MyFTPHelper.FTPNewLine)) { return; } ListenDataPort(); PostMessageToConsoleWithLock("开始下载" + filename); FTPCommand downloadCommand = new FTPCommand("RETR", new string[] { filename }); if (!SendMessageToServerAndWaitReply(downloadCommand.ToString() + MyFTPHelper.FTPNewLine)) { return; } try { FileStream fs = File.OpenWrite(downloadDirectory + filename); NetworkStream dataStream = dataClient.GetStream(); currenttransfer = new FileTransfer() { networkStream = dataStream, filestream = fs, }; currenttransfer.DownloadAsync(() => { fs.Close(); dataStream.Close(); PostMessageToConsoleWithLock("完成下载"); }); } catch (Exception exc) { PostMessageToConsoleWithLock(exc.Message); } }
public void UploadFile(string filepath) { FTPCommand portCommand = new FTPCommand("PORT", new string[] { controlPort.ToString() }); if (!SendMessageToServerAndWaitReply(portCommand.ToString() + MyFTPHelper.FTPNewLine)) { return; } ListenDataPort(); PostMessageToConsoleWithLock("开始上传" + Path.GetFileName(filepath)); FTPCommand uploadCommand = new FTPCommand("STOR", new string[] { Path.GetFileName(Path.GetFileName(filepath)) }); if (!SendMessageToServerAndWaitReply(uploadCommand.ToString() + MyFTPHelper.FTPNewLine)) { return; } try { FileStream fs = File.OpenRead(filepath); NetworkStream dataStream = dataClient.GetStream(); currenttransfer = new FileTransfer() { networkStream = dataStream, filestream = fs, }; currenttransfer.UploadAsync(() => { fs.Close(); dataStream.Close(); PostMessageToConsoleWithLock("完成上传"); }); } catch (Exception exc) { PostMessageToConsoleWithLock(exc.Message); } }
public void UpdateList() { FTPCommand fileListCommand = new FTPCommand("LIST", null); SendMessageToServerAndWaitReply(fileListCommand.ToString() + MyFTPHelper.FTPNewLine); }
public void Start() { while (true) { try { FTPCommand?ncommand = ReadNextCommand(); if (ncommand == null) { continue; } else { FTPCommand command = ncommand.Value; FTPReply reply = new FTPReply() { replyCode = FTPReply.Code_SyntaxError }; switch (command.controlCommand) { case "USER": //USER 指定账号 if (command.parameters.Length != 1) { reply = new FTPReply() { replyCode = FTPReply.Code_SyntaxErrorPara, }; break; } user.username = command.parameters[0]; break; case "PASS": //PASS 指定密码 if (command.parameters.Length != 1) { reply = new FTPReply() { replyCode = FTPReply.Code_SyntaxErrorPara, }; break; } user.password = command.parameters[0]; if (serverDispatcher.CheckUserWithLock(user)) { Logined = true; serverDispatcher.PostMessageFromClient("已成功登录", this); reply = new FTPReply() { replyCode = FTPReply.Code_UserLoggedIn, post = "login success" }; } else { serverDispatcher.PostMessageFromClient("密码或用户名有误", this); reply = new FTPReply() { replyCode = FTPReply.Code_UserNotLogIn, post = "login fail" }; } break; case "LIST": //LIST 返回服务器的文件目录(标准中不指定返回格式,格式为我们自定义) reply = new FTPReply() { replyCode = FTPReply.Code_FileList, post = serverDispatcher.GetEncodedFileList() }; break; case "STOR": //STOR 客户端上传文件 if (command.parameters.Length != 1) { reply = new FTPReply() { replyCode = FTPReply.Code_SyntaxErrorPara }; break; } string filename = command.parameters[0]; FileStream downloadFileStream = File.OpenWrite(serverDispatcher.GetCurrentDirectory() + filename); NetworkStream downloadDataStream = dataClient.GetStream(); if (downloadFileStream == null) { reply = new FTPReply() { replyCode = FTPReply.Code_CantOopenDataConnection }; break; } if (dataClient == null) { reply = new FTPReply() { replyCode = FTPReply.Code_ConnectionClosed }; break; } currentTransfer = new FileTransfer() { networkStream = downloadDataStream, filestream = downloadFileStream, }; currentTransfer.DownloadAsync(() => { downloadDataStream.Close(); downloadFileStream.Close(); serverDispatcher.PostMessageFromClient("文件上传完成", this); } ); reply = new FTPReply() { replyCode = FTPReply.Code_ConnectionClosed }; break; case "RETR": //RETR 客户端下载文件 if (command.parameters.Length != 1) { reply = new FTPReply() { replyCode = FTPReply.Code_SyntaxErrorPara }; break; } FileStream uploadFileStream = serverDispatcher.OpenFileStreamInfileList(command.parameters[0]); NetworkStream uploadDataStream = dataClient.GetStream(); if (uploadFileStream == null) { reply = new FTPReply() { replyCode = FTPReply.Code_CantOopenDataConnection }; break; } if (dataClient == null) { reply = new FTPReply() { replyCode = FTPReply.Code_ConnectionClosed }; break; } currentTransfer = new FileTransfer() { networkStream = uploadDataStream, filestream = uploadFileStream, }; currentTransfer.UploadAsync(() => { uploadDataStream.Close(); uploadFileStream.Close(); serverDispatcher.PostMessageFromClient("文件上传完成", this); } ); reply = new FTPReply() { replyCode = FTPReply.Code_ConnectionClosed }; break; case "ABOR": //QUIT 关闭与服务器的连接 throw new NotImplementedException(); case "QUIT": //ABOR 放弃之前的文件传输 throw new NotImplementedException(); case "PASV": //PASV 数据线程让服务器监听特定端口 throw new NotImplementedException(); case "PORT": //PORT 客户端的控制端口为N,数据端口为N+1,服务器的控制端口为21,数据端口为20 if (command.parameters.Length != 1 || !int.TryParse(command.parameters[0], out controlPort)) { reply = new FTPReply() { replyCode = FTPReply.Code_SyntaxErrorPara }; break; } if (!serverDispatcher.CheckDataPortLegal(controlPort, this)) { reply = new FTPReply() { replyCode = FTPReply.Code_CantOopenDataConnection }; break; } var remoteDataEnd = (IPEndPoint)controlClient.Client.RemoteEndPoint; remoteDataEnd.Port = controlPort + 1; dataClient = new TcpClient(); reply = new FTPReply() { replyCode = FTPReply.Code_DataConnectionOpen }; dataClient.ConnectAsync(remoteDataEnd.Address.MapToIPv4(), remoteDataEnd.Port); serverDispatcher.PostMessageFromClient("与" + user.username + "建立数据连接", this); break; default: break; } MyFTPHelper.WriteToNetStream(reply.ToString(), controlStream); } } catch (System.IO.IOException exc) { serverDispatcher.PostMessageFromClient(exc.Message, this); controlClient.Close(); controlStream.Close(); return; } } }