Criando um Project Console 1 New/Project/Console Application Código Fonte Imports System.Net.Sockets Imports System.Text Imports System.Net Public Module FtpExemplo Public Sub Main() ' Conecta a um servidor FTP. Dim FTP As New FtpClient FTP.Connect("ftp.adobe.com", "anonymous", "ftpuser@adobe.com") ' Solicita o arquivo Dim Stream As NetworkStream = FTP.DownloadFile("license.txt", True) ' Copia os dados em pacote de 1K Dim fs As New System.IO.FileStream("c:\license.txt", IO.FileMode.Create) Dim BytesRead As Integer Do Dim Bytes(1024) As Byte BytesRead = Stream.Read(Bytes, 0, Bytes.Length) fs.write(bytes, 0, BytesRead) Loop While BytesRead > 0 -- ' Fecha a conexão de rede e o arquivo -- Stream.Close() fs.close() ------ ' Restaura a msg de confirmação do server ------ FTP.ConfirmDownloadComplete() Console.WriteLine("Pressione Enter para desconectar") Console.ReadLine() FTP.Disconnect() End Module
Public Class FtpClient Inherits System.ComponentModel.Component ' Conexão TCP interna Private Client As New TcpClient Private Stream As NetworkStream ' Estado da conexão Private _Connected As Boolean = False Public ReadOnly Property Connected() As Boolean Get Return _Connected End Get End Property ' Alguns comandos constates Private Class Commands Public Const User As String = "USER " Public Const Password As String = "PASS " Public Const Quit As String = "QUIT" & vbnewline Public Const GetFile As String = "RETR " Public Const UsePassiveMode As String = "PASV" & vbnewline Public Const UseBinary As String = "TYPE I" & vbnewline Public Const UseAscii As String = "TYPE A" & vbnewline End Class Private Enum ReturnCodes ServiceReady = 220 Accepted = 200 PasswordRequired = 331 UserLoggedIn = 230 EnteringPassiveMode = 227 StartingTransferAlreadyOpen = 125 StartingTransferOpening = 150 TransferComplete = 226 End Enum Public Sub Connect(ByVal servername As String, ByVal username As String, ByVal password As String) If Connected Then Me.Disconnect() ' Conecta ao servidor FTP sempre na ' porta 21 Client.Connect(serverName, 21) Stream = Client.GetStream()
' Envia o nome do usuário Dim Response As String Response = GetResponse() Response = Send(Commands.User & username & vbnewline) If CheckCode(Response, ReturnCodes.PasswordRequired) Then ' Envia a password Response = Send(Commands.Password & password & vbnewline) If Not (CheckCode(Response, ReturnCodes.UserLoggedIn)) And Not (CheckCode(Response, ReturnCodes.ServiceReady)) Then Throw New ApplicationException("Não foi possível efetuar login.") _Connected = True -- ' Uma breve pausa no caso de ainda ' existir dados para serem retornados ' 300 milisegundos -- System.Threading.Thread.Sleep(300) If Stream.DataAvailable Then GetResponse() Public Sub Disconnect() If Connected Then If Not TransferClient Is Nothing Then TransferClient.Close() Send(Commands.Quit) _Connected = False ' Segunda conexão para recuperar ' o arquivo Private TransferClient As TcpClient Private TransferEndpoint As IPEndPoint Public Function DownloadFile(ByVal filename As String, ByVal binarymode As Boolean) As NetworkStream ' Cria uma conexão para a segunda ' porta em mode passivo CreateTransferClient() TransferClient.Connect(TransferEndpoint) SetMode(binaryMode) Dim Response As String = Send(Commands.GetFile & filename & vbnewline)
If Not CheckCode(Response, ReturnCodes.StartingTransferAlreadyOpen) And Not (CheckCode(Response, ReturnCodes.StartingTransferOpening)) Then Throw New ApplicationException("Não foi possível abrir a conexão.") ' Deixa o cliente ler os dados para ' um stream de rede. ' Isso é mais eficiente que criar e ' retonar um array de byte, porém ' confia no cliente para fechar um ' stream. Return TransferClient.GetStream() Private Sub CreateTransferClient() Dim Response As String = Send(Commands.UsePassiveMode) If Not CheckCode(Response, ReturnCodes.EnteringPassiveMode) Then Throw New ApplicationException("Erro entrando em modo passivo.") ' O endereço IP e o número da porta ' á atachado para a resposta. ' Recupera esses detalhes. Dim StartPos As Integer = Response.IndexOf("(") Dim EndPos As Integer = Response.IndexOf(")") Dim IPAndPort As String = Response.Substring(StartPos + 1, _ EndPos - StartPos - 1) Dim IPParts() As String = IPAndPort.Split(","c) Dim IP As String = IPParts(0) + "." + IPParts(1) + "." + IPParts(2) + "." + IPParts(3) Dim Port As Integer = Convert.ToInt32(IPParts(4)) * 256 + Convert.ToInt32(IPParts(5)) ' Cria uma conexão de tranferencia ' de dados. TransferClient = New TcpClient TransferEndpoint = New IPEndPoint(IPAddress.Parse(IP), Port) Private Sub SetMode(ByVal binarymode As Boolean) Dim Response As String If binarymode Then Response = Send(Commands.UseBinary) Else Response = Send(Commands.UseAscii) If Not CheckCode(Response, ReturnCodes.Accepted) Then Throw New ApplicationException("Não foi possível trocar o modo.")
Public Sub ConfirmDownloadComplete() Dim Response As String = GetResponse() CheckCode(Response, ReturnCodes.TransferComplete) Private Function Send(ByVal message As String) As String ' Envia um comando em formato ASCII Dim MessageBytes() As Byte = Encoding.ASCII.GetBytes(message) Stream.Write(MessageBytes, 0, MessageBytes.Length) Debug.WriteLine(message) ' Retona o código da resposta Return GetResponse() Private Function GetResponse() As String ' Recupera todas as linha diponíveis Dim Character As String Dim Response As String = "" Do Do Character = Chr(Stream.ReadByte()).ToString() Response &= Character Loop Until Character = Chr(10) 'System.Threading.Thread.Sleep(5) Loop While Stream.DataAvailable Response = Response.Trim(New Char() {Chr(13), Chr(10)}) Debug.WriteLine(Response) Return Response Private Function CheckCode(ByVal response As String, ByVal expectedcode As ReturnCodes) As Boolean Return Val(response.Substring(0, 3)) = expectedcode Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then Disconnect() MyBase.Dispose(disposing) End Class
Resultado Obs: Caso o arquivo c:\licence.txt já exista um erro será gerado. Voltar para Softwise