public async Task DownloadFileAsync(System.IO.Stream LocalFileStream, String RemoteFilename) { if (!IsBusy) { ftpFileInfo = null; IsBusy = true; ftpFileInfo = new FtpFileOperationInfo(LocalFileStream, RemoteFilename, false); ftpCommand = FtpCommand.Type; logger.AddLog("FTPClient -> TYPE I\r\n"); await FtpCommandSocket.SendDataAsync("TYPE I\r\n"); } }
public async Task GetDirectoryListingAsync() { if (!IsBusy) { fileListingData = null; ftpFileInfo = null; IsBusy = true; ftpCommand = FtpCommand.Passive; logger.AddLog("FTPClient -> PASV\r\n"); await FtpCommandSocket.SendDataAsync("PASV\r\n"); } }
async void FtpClientSocket_DataReceived(object sender, DataReceivedEventArgs e) { String Response = System.Text.Encoding.UTF8.GetString(e.GetData(), 0, e.GetData().Length); Response = Response.Trim(); logger.AddLog(String.Format("FTPServer -> {0}", Response)); switch (ftpPassiveOperation) { case FtpPassiveOperation.FileDownload: ftpCommand = FtpCommand.None; if (Response.StartsWith("150") || Response.StartsWith("125")) { IsBusy = true; DataReader dataReader = new DataReader(FtpDataChannel.InputStream); dataReader.InputStreamOptions = InputStreamOptions.Partial; while (!(await dataReader.LoadAsync(32768)).Equals(0)) { IBuffer databuffer = dataReader.DetachBuffer(); RaiseFtpFileTransferProgressedEvent(databuffer.Length, false); await ftpFileInfo.LocalFileStream.WriteAsync(databuffer.ToArray(), 0, Convert.ToInt32(databuffer.Length)); } await ftpFileInfo.LocalFileStream.FlushAsync(); dataReader.Dispose(); dataReader = null; //FtpDataChannel.Dispose(); //FtpDataChannel = null; RaiseFtpFileDownloadSucceededEvent(ftpFileInfo.LocalFileStream, ftpFileInfo.RemoteFile); } else if (Response.StartsWith("226")) { IsBusy = false; ftpPassiveOperation = FtpPassiveOperation.None; } else { IsBusy = false; ftpPassiveOperation = FtpPassiveOperation.None; RaiseFtpFileDownloadFailedEvent(ftpFileInfo.LocalFileStream, ftpFileInfo.RemoteFile, FtpFileTransferFailureReason.FileDoesNotExist); } break; case FtpPassiveOperation.FileUpload: ftpCommand = FtpCommand.None; if (Response.StartsWith("150") || Response.StartsWith("125")) { IsBusy = true; DataWriter dataWriter = new DataWriter(FtpDataChannel.OutputStream); byte[] data = new byte[32768]; while (!(await ftpFileInfo.LocalFileStream.ReadAsync(data, 0, data.Length)).Equals(0)) { dataWriter.WriteBytes(data); await dataWriter.StoreAsync(); RaiseFtpFileTransferProgressedEvent(Convert.ToUInt32(data.Length), true); } await dataWriter.FlushAsync(); dataWriter.Dispose(); dataWriter = null; FtpDataChannel.Dispose(); FtpDataChannel = null; } else if (Response.StartsWith("226")) { IsBusy = false; ftpPassiveOperation = FtpPassiveOperation.None; RaiseFtpFileUploadSucceededEvent(ftpFileInfo.LocalFileStream, ftpFileInfo.RemoteFile); ftpFileInfo = null; } else { IsBusy = false; ftpPassiveOperation = FtpPassiveOperation.None; RaiseFtpFileUploadFailedEvent(ftpFileInfo.LocalFileStream, ftpFileInfo.RemoteFile, FtpFileTransferFailureReason.FileDoesNotExist); ftpFileInfo = null; } break; case FtpPassiveOperation.ListDirectory: ftpCommand = FtpCommand.None; if (Response.StartsWith("150") || Response.StartsWith("125")) { IsBusy = true; DataReader dataReader = new DataReader(FtpDataChannel.InputStream); dataReader.InputStreamOptions = InputStreamOptions.Partial; fileListingData = new List <byte>(); while (!(await dataReader.LoadAsync(1024)).Equals(0)) { fileListingData.AddRange(dataReader.DetachBuffer().ToArray()); } dataReader.Dispose(); dataReader = null; FtpDataChannel.Dispose(); FtpDataChannel = null; Gb2312Encoding encoding = new Gb2312Encoding(); String listingData = encoding.GetString(fileListingData.ToArray(), 0, fileListingData.ToArray().Length); String[] listings = listingData.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); List <String> Filenames = new List <String>(); List <String> Directories = new List <String>(); foreach (String listing in listings) { if (listing.StartsWith("drwx") || listing.Contains("<DIR>")) { Directories.Add(listing.Split(new char[] { ' ' }).Last()); } else { Filenames.Add(listing.Split(new char[] { ' ' }).Last()); } } RaiseFtpDirectoryListedEvent(Directories.ToArray(), Filenames.ToArray()); } else if (Response.StartsWith("226")) { IsBusy = false; ftpFileInfo = null; ftpPassiveOperation = FtpPassiveOperation.None; } else { IsBusy = false; ftpFileInfo = null; ftpPassiveOperation = FtpPassiveOperation.None; } break; case FtpPassiveOperation.None: switch (ftpCommand) { case FtpCommand.Username: if (Response.StartsWith("501")) { IsBusy = false; RaiseFtpAuthenticationFailedEvent(); break; } this.ftpCommand = FtpCommand.Password; logger.AddLog(String.Format("FTPClient -> PASS {0}\r\n", this.Password)); await FtpCommandSocket.SendDataAsync(String.Format("PASS {0}\r\n", this.Password)); break; case FtpCommand.Password: this.ftpCommand = FtpCommand.None; IsBusy = false; if (Response.Contains("530")) { RaiseFtpAuthenticationFailedEvent(); } else { RaiseFtpAuthenticationSucceededEvent(); } break; case FtpCommand.ChangeWorkingDirectory: IsBusy = false; if (Response.StartsWith("550")) { RaiseFtpDirectoryChangedFailedEvent(this.RemoteDirectory); } else { RaiseFtpDirectoryChangedSuccededEvent(this.RemoteDirectory); } break; case FtpCommand.PresentWorkingDirectory: if (Response.StartsWith("257")) { IsBusy = false; RaiseFtpPresentWorkingDirectoryReceivedEvent(Response.Split(new Char[] { ' ', '"' }, StringSplitOptions.RemoveEmptyEntries)[1]); } break; case FtpCommand.Type: ftpCommand = FtpCommand.Passive; logger.AddLog("FTPClient -> PASV\r\n"); await FtpCommandSocket.SendDataAsync("PASV\r\n"); break; case FtpCommand.Passive: if (Response.StartsWith("227")) { await PrepareDataChannelAsync(Response); if (ftpFileInfo != null) { if (ftpFileInfo.IsUpload) { ftpPassiveOperation = FtpPassiveOperation.FileUpload; logger.AddLog(String.Format("FTPClient -> STOR {0}\r\n", ftpFileInfo.RemoteFile)); await FtpCommandSocket.SendDataAsync(String.Format("STOR {0}\r\n", ftpFileInfo.RemoteFile)); } else { ftpPassiveOperation = FtpPassiveOperation.FileDownload; logger.AddLog(String.Format("FTPClient -> RETR {0}\r\n", ftpFileInfo.RemoteFile)); await FtpCommandSocket.SendDataAsync(String.Format("RETR {0}\r\n", ftpFileInfo.RemoteFile)); } } else { fileListingData = new List <byte>(); ftpPassiveOperation = FtpPassiveOperation.ListDirectory; logger.AddLog("FTPClient -> LIST\r\n"); await FtpCommandSocket.SendDataAsync("LIST\r\n"); } } break; case FtpCommand.Logout: ftpCommand = FtpCommand.None; break; case FtpCommand.None: break; } break; } }