Programando en .NET (c#, VB.NET, ASP.NET)

Nuevo usuario | Conectarse

Programando en .NET

freelance web desarrollador programador autonomo .net framework microsoft aplicacion escritorio vb.net ASP.NET VB.NET C# DLL HTML JavaScript VBA VBScript CSS SQL Server sqlServer Access MySQL

Categorías

Top Mas Visitados

Comentarios Recientes

Mejores Posts

Archivo

Links

Compartir

Contacto

Libreria de trabajo y conexión FTP

Por Alvaro
11/03/2009

Enviar esta pagina a un amigo.    

Creamos un formulario y una clase, en el formulario añadimos una barra de progreso, llamada pbFile y un label, llámalo lblMessages.
Los datos de conexión los leemos de los settings, en las propiedades del proyecto, créalos tal y como se leen en el código.

Public Class frmFTP

    Private WithEvents FTP As clsFTP

    Private Folder As String

    Private Delegate Sub ActivateProgress(ByVal Length As Long)

    Private Delegate Sub updateProgress()

 

    Private Sub frmFTP_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

        FTP.CloseConnection()

        FTP = Nothing

        My.Settings.Source = Folder

        My.Settings.Save()

    End Sub

 

    Private Sub frmFTP_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        MsgBox("Conectando con el servidor FTP.", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "Conectando")

        Me.Cursor = Cursors.WaitCursor

        FTP = New clsFTP

        Folder = My.Settings.Source

        With My.Settings

            FTP.RemoteHost = .RemoteHost

            FTP.RemotePassword = .RemotePassword

            FTP.RemotePath = .RemotePath

            FTP.RemoteUser = .RemoteUser

        End With

        If FTP.Login Then

            FTP.SetBinaryMode(True)

            FTP.ChangeDirectory("carpeta_donde_subir_archivos")

            MsgBox("Conectado.", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "Connecting")

        Else

            MsgBox("No se pudo conectar con el servidor FTP.", MsgBoxStyle.Critical + MsgBoxStyle.OkOnly, "Error en la conexion")

        End If

        Me.Cursor = Cursors.Arrow

    End Sub

 

    Private Sub FTPUpload(ByVal Path As String)

        lblMessages.Text = "Subiendo..." & Path

        FTP.UploadFile(Path)

    End Sub

 

    Private Sub btnUpload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpload.Click

        Dim Files As String(), File As String

        lblMessages.Text = "Leyendo archivos..."

        Files = IO.Directory.GetFiles(Folder, "*.*")

        For Each File In Files

            lblMessages.Text = "Subiendo " & IO.Path.GetFileNameWithoutExtension(File)

            My.Application.DoEvents()

            FTPUpload(File)

        Next

        lblMessages.Text = "Hecho."

    End Sub

 

    Private Sub updateProgressHandler()

        pbFile.PerformStep()

        My.Application.DoEvents()

    End Sub

 

    Private Sub ActivateProgressHandler(ByVal Length As Long)

        pbFile.Maximum = Length

        pbFile.Minimum = 0

        pbFile.Value = 1

        pbFile.Step = 512

        pbFile.Refresh()

    End Sub

 

    Private Sub ActivateProcessFTP(ByVal Length As Long) Handles FTP.ActivateProgress

        If Me.InvokeRequired Then 'are we running on a secondary thread

            Dim d As New ActivateProgress(AddressOf ActivateProgressHandler)

            Me.Invoke(d, New Object() {Length})

        Else

            ActivateProgressHandler(Length)

        End If

    End Sub

 

    Private Sub ProcessFTP() Handles FTP.Progress

        If Me.InvokeRequired Then 'are we running on a secondary thread

            Dim d As New updateProgress(AddressOf updateProgressHandler)

            Me.Invoke(d, New Object() {})

        Else

            updateProgressHandler()

        End If

    End Sub

 

End Class

Y esta es la clase que realmente hace todo, la ftp, pégalo en el fichero clase. Listo!

Imports System

Imports System.Net

Imports System.IO

Imports System.IO.FileInfo

Imports System.Text

Imports System.Net.Sockets

 

Public Class clsFTP

 

#Region "Main Class Variable Declarations"

Private m_sRemoteHost, m_sRemotePath, m_sRemoteUser As String

Private m_sRemotePassword, m_sMess As String

Private m_iRemotePort, m_iBytes As Int32

Private m_objClientSocket As Socket

 

Private m_iRetValue As Int32

Private m_bLoggedIn As Boolean ' Change to loggedIn

Private m_sMes, m_sReply As String

 

' Set the size of the packet that is used to read and

' write data to the FTP Server to the spcified size below.

Public Const BLOCK_SIZE = 512

Private m_aBuffer(BLOCK_SIZE) As Byte

Private ASCII As Encoding = Encoding.ASCII

 

Public Event Progress()

Public Event ActivateProgress(ByVal Total As Long)

 

' General variables

Private m_sMessageString As String

#End Region

 

#Region "Class Constructors"

'

' Main class constructor.

Public Sub New()

m_sRemoteHost = "microsoft"

m_sRemotePath = "."

m_sRemoteUser = "anonymous"

m_sRemotePassword = ""

m_sMessageString = ""

m_iRemotePort = 21

m_bLoggedIn = False

End Sub

 

' Parametized constructor.

Public Sub New(ByVal sRemoteHost As String, _

ByVal sRemotePath As String, _

ByVal sRemoteUser As String, _

ByVal sRemotePassword As String, _

ByVal iRemotePort As Int32)

m_sRemoteHost = sRemoteHost

m_sRemotePath = sRemotePath

m_sRemoteUser = sRemoteUser

m_sRemotePassword = sRemotePassword

m_sMessageString = ""

m_iRemotePort = iRemotePort

m_bLoggedIn = False

End Sub

#End Region

 

#Region "Public Properties"

'

' Set/Get the name of the FTP Server.

Public Property RemoteHost() As String

Get

Return m_sRemoteHost

End Get

Set(ByVal Value As String)

m_sRemoteHost = Value

End Set

End Property

 

' Set/Get the FTP Port Number.

Public Property RemotePort() As Int32

Get

Return m_iRemotePort

End Get

Set(ByVal Value As Int32)

m_iRemotePort = Value

End Set

End Property

 

' Set/Get the remote path.

Public Property RemotePath() As String

Get

Return m_sRemotePath

End Get

Set(ByVal Value As String)

m_sRemotePath = Value

End Set

End Property

 

' Set the remote password.

Public Property RemotePassword() As String

Get

Return m_sRemotePassword

End Get

Set(ByVal Value As String)

m_sRemotePassword = Value

End Set

End Property

 

' Set/Get the remote user.

Public Property RemoteUser() As String

Get

Return m_sRemoteUser

End Get

Set(ByVal Value As String)

m_sRemoteUser = Value

End Set

End Property

 

' Set the class messagestring.

Public Property MessageString() As String

Get

Return m_sMessageString

End Get

Set(ByVal Value As String)

m_sMessageString = Value

End Set

End Property

 

#End Region

 

#Region "Public Subs and Functions"

'

' Return a list of files within a string() array from the

' file system.

Public Function GetFileList(ByVal sMask As String) As String()

Dim cSocket As Socket

Dim bytes As Int32

Dim seperator As Char = ControlChars.Lf

Dim mess() As String

 

m_sMes = ""

If (Not (m_bLoggedIn)) Then

Login()

End If

 

cSocket = CreateDataSocket()

SendCommand("NLST " & sMask)

 

If (Not (m_iRetValue = 150 Or m_iRetValue = 125)) Then

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

m_sMes = ""

Do While (True)

m_aBuffer.Clear(m_aBuffer, 0, m_aBuffer.Length)

bytes = cSocket.Receive(m_aBuffer, m_aBuffer.Length, 0)

m_sMes += ASCII.GetString(m_aBuffer, 0, bytes)

 

If (bytes < m_aBuffer.Length) Then

Exit Do

End If

Loop

 

mess = m_sMes.Split(seperator)

cSocket.Close()

ReadReply()

 

If (m_iRetValue <> 226) Then

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

Return mess

End Function

 

'

' Get the size of the file on the FTP Server.

Public Function GetFileSize(ByVal sFileName As String) As Long

Dim size As Long

 

If (Not (m_bLoggedIn)) Then

Login()

End If

 

SendCommand("SIZE " & sFileName)

size = 0

 

If (m_iRetValue = 213) Then

size = Int64.Parse(m_sReply.Substring(4))

Else

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

Return size

End Function

 

' Log into the FTP Server.

Public Function Login() As Boolean

m_objClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

Dim ep As New IPEndPoint(Dns.Resolve(m_sRemoteHost).AddressList(0), m_iRemotePort)

 

Try

m_objClientSocket.Connect(ep)

Catch ex As Exception

MessageString = m_sReply

Throw New IOException("Couldn't connect to remote server")

End Try

 

ReadReply()

If (m_iRetValue <> 220) Then

CloseConnection()

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

SendCommand("USER " & m_sRemoteUser)

If (Not (m_iRetValue = 331 Or m_iRetValue = 230)) Then

Cleanup()

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

If (m_iRetValue <> 230) Then

SendCommand("PASS " & m_sRemotePassword)

If (Not (m_iRetValue = 230 Or m_iRetValue = 202)) Then

Cleanup()

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

End If

 

m_bLoggedIn = True

ChangeDirectory(m_sRemotePath)

 

' Return the end result.

Return m_bLoggedIn

End Function

 

' If the value of mode is true, set binary mode for downloads.

' Else, set Ascii mode.

Public Sub SetBinaryMode(ByVal bMode As Boolean)

 

If (bMode) Then

SendCommand("TYPE I")

Else

SendCommand("TYPE A")

End If

 

If (m_iRetValue <> 200) Then

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

End Sub

 

' Download a file to the Assembly's local directory, keeping the same file name.

Public Sub DownloadFile(ByVal sFileName As String)

DownloadFile(sFileName, "", False)

End Sub

 

' Download a remote file to the Assembly's local

' directory, keeping the same file name, and set

' the resume flag.

Public Sub DownloadFile(ByVal sFileName As String, _

ByVal bResume As Boolean)

DownloadFile(sFileName, "", bResume)

End Sub

 

'

' Download a remote file to a local file name which can

' include a path. The local file name will be created or

' overwritten, but the path must exist.

Public Sub DownloadFile(ByVal sFileName As String, _

ByVal sLocalFileName As String)

DownloadFile(sFileName, sLocalFileName, False)

End Sub

 

'

' Download a remote file to a local file name which can

' include a path, and set the resume flag. The local file

' name will be created or overwritten, but the path must

' exist.

Public Sub DownloadFile(ByVal sFileName As String, _

ByVal sLocalFileName As String, _

ByVal bResume As Boolean)

Dim st As Stream

Dim output As FileStream

Dim cSocket As Socket

Dim offset, npos As Long

 

If (Not (m_bLoggedIn)) Then

Login()

End If

 

SetBinaryMode(True)

 

If (sLocalFileName.Equals("")) Then

sLocalFileName = sFileName

End If

 

If (Not (File.Exists(sLocalFileName))) Then

st = File.Create(sLocalFileName)

st.Close()

End If

 

output = New FileStream(sLocalFileName, FileMode.Open)

cSocket = CreateDataSocket()

offset = 0

 

If (bResume) Then

offset = output.Length

 

If (offset > 0) Then

SendCommand("REST " & offset)

If (m_iRetValue <> 350) Then

'throw new IOException(reply.Substring(4));

'Some servers may not support resuming.

offset = 0

End If

End If

 

If (offset > 0) Then

npos = output.Seek(offset, SeekOrigin.Begin)

End If

End If

 

SendCommand("RETR " & sFileName)

 

If (Not (m_iRetValue = 150 Or m_iRetValue = 125)) Then

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

Do While (True)

m_aBuffer.Clear(m_aBuffer, 0, m_aBuffer.Length)

m_iBytes = cSocket.Receive(m_aBuffer, m_aBuffer.Length, 0)

output.Write(m_aBuffer, 0, m_iBytes)

 

If (m_iBytes <= 0) Then

Exit Do

End If

Loop

 

output.Close()

If (cSocket.Connected) Then

cSocket.Close()

End If

 

ReadReply()

If (Not (m_iRetValue = 226 Or m_iRetValue = 250)) Then

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

End Sub

 

' Upload a file.

Public Sub UploadFile(ByVal sFileName As String)

UploadFile(sFileName, False)

End Sub

 

' Upload a file and set the resume flag.

Public Sub UploadFile(ByVal sFileName As String, ByVal bResume As Boolean)

Dim cSocket As Socket

Dim offset As Long

Dim input As FileStream

Dim bFileNotFound As Boolean

 

If Not m_bLoggedIn Then

Login()

End If

 

cSocket = CreateDataSocket()

offset = 0

 

If bResume Then

Try

SetBinaryMode(True)

offset = GetFileSize(sFileName)

Catch ex As Exception

offset = 0

End Try

End If

 

If (offset > 0) Then

SendCommand("REST " & offset)

If (m_iRetValue <> 350) Then

'throw new IOException(reply.Substring(4));

'Remote server may not support resuming.

offset = 0

End If

End If

 

SendCommand("STOR " & Path.GetFileName(sFileName))

If (Not (m_iRetValue = 125 Or m_iRetValue = 150)) Then

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

' Check to see if the file exists before the upload.

bFileNotFound = False

If File.Exists(sFileName) Then

' Open input stream to read source file

input = New FileStream(sFileName, FileMode.Open)

If (offset <> 0) Then

input.Seek(offset, SeekOrigin.Begin)

End If

 

' Upload the file

m_iBytes = input.Read(m_aBuffer, 0, m_aBuffer.Length)

Dim F As New FileInfo(sFileName)

RaiseEvent ActivateProgress(F.Length)

Do While (m_iBytes > 0)

RaiseEvent Progress()

cSocket.Send(m_aBuffer, m_iBytes, 0)

m_iBytes = input.Read(m_aBuffer, 0, m_aBuffer.Length)

Loop

RaiseEvent Progress()

F = Nothing

input.Close()

Else

bFileNotFound = True

End If

 

If cSocket.Connected Then cSocket.Close()

 

' No point in reading the return value if the file was not found.

If (bFileNotFound) Then

MessageString = m_sReply

Throw New IOException("The file: " & sFileName & " was not found. Can not upload the file to the FTP Site.")

End If

 

ReadReply()

If (Not (m_iRetValue = 226 Or m_iRetValue = 250)) Then

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

End Sub

 

'

' Delete a file from the remote FTP server.

Public Function DeleteFile(ByVal sFileName As String) As Boolean

Dim bResult As Boolean

 

bResult = True

If (Not (m_bLoggedIn)) Then

Login()

End If

 

SendCommand("DELE " & sFileName)

If (m_iRetValue <> 250) Then

bResult = False

MessageString = m_sReply

End If

 

' Return the final result.

Return bResult

End Function

 

'

' Rename a file on the remote FTP server.

Public Function RenameFile(ByVal sOldFileName As String, _

ByVal sNewFileName As String) As Boolean

Dim bResult As Boolean

 

bResult = True

If (Not (m_bLoggedIn)) Then

Login()

End If

 

SendCommand("RNFR " & sOldFileName)

If (m_iRetValue <> 350) Then

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

' known problem

' rnto will not take care of existing file.

' i.e. It will overwrite if newFileName exist

SendCommand("RNTO " & sNewFileName)

If (m_iRetValue <> 250) Then

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

Return bResult

End Function

 

'

' Create a directory on the remote FTP server.

Public Function CreateDirectory(ByVal sDirName As String) As Boolean

Dim bResult As Boolean

 

bResult = True

If (Not (m_bLoggedIn)) Then

Login()

End If

 

SendCommand("MKD " & sDirName)

If (m_iRetValue <> 257) Then

bResult = False

MessageString = m_sReply

End If

 

' Return the final result.

Return bResult

End Function

 

'

' Delete a directory on the remote FTP server.

Public Function RemoveDirectory(ByVal sDirName As String) As Boolean

Dim bResult As Boolean

 

bResult = True

If (Not (m_bLoggedIn)) Then

Login()

End If

 

SendCommand("RMD " & sDirName)

If (m_iRetValue <> 250) Then

bResult = False

MessageString = m_sReply

End If

 

' Return the final result.

Return bResult

End Function

 

'

' Change the current working directory on the remote FTP

' server.

Public Function ChangeDirectory(ByVal sDirName As String) As Boolean

Dim bResult As Boolean

 

bResult = True

If (sDirName.Equals(".")) Then

Exit Function

End If

 

If (Not (m_bLoggedIn)) Then

Login()

End If

 

SendCommand("CWD " & sDirName)

If (m_iRetValue <> 250) Then

bResult = False

MessageString = m_sReply

End If

 

Me.m_sRemotePath = sDirName

 

' Return the final result.

Return bResult

End Function

 

'

' Close the FTP connection.

Public Sub CloseConnection()

If (Not (m_objClientSocket Is Nothing)) Then

SendCommand("QUIT")

End If

 

Cleanup()

End Sub

 

#End Region

 

#Region "Private Subs and Functions"

'

' Read the reply from the FTP Server

Private Sub ReadReply()

m_sMes = ""

m_sReply = ReadLine()

m_iRetValue = Int32.Parse(m_sReply.Substring(0, 3))

End Sub

 

'

' Clean up some variables.

Private Sub Cleanup()

If Not (m_objClientSocket Is Nothing) Then

m_objClientSocket.Close()

m_objClientSocket = Nothing

End If

 

m_bLoggedIn = False

End Sub

 

'

' Read a line from the server.

Private Function ReadLine(Optional ByVal bClearMes As Boolean = False) As String

Dim seperator As Char = ControlChars.Lf

Dim mess() As String

 

If (bClearMes) Then

m_sMes = ""

End If

Do While (True)

m_aBuffer.Clear(m_aBuffer, 0, BLOCK_SIZE)

m_iBytes = m_objClientSocket.Receive(m_aBuffer, m_aBuffer.Length, 0)

m_sMes += ASCII.GetString(m_aBuffer, 0, m_iBytes)

If (m_iBytes < m_aBuffer.Length) Then

Exit Do

End If

Loop

 

mess = m_sMes.Split(seperator)

If (m_sMes.Length > 2) Then

m_sMes = mess(mess.Length - 2)

Else

m_sMes = mess(0)

End If

 

If (Not (m_sMes.Substring(3, 1).Equals(" "))) Then

Return ReadLine(True)

End If

 

Return m_sMes

End Function

 

'

' Send a command to the FTP Server.

Private Sub SendCommand(ByVal sCommand As String)

sCommand = sCommand & ControlChars.CrLf

Dim cmdbytes As Byte() = ASCII.GetBytes(sCommand)

 

m_objClientSocket.Send(cmdbytes, cmdbytes.Length, 0)

ReadReply()

End Sub

 

'

' Create a Data socket.

Private Function CreateDataSocket() As Socket

Dim index1, index2, len As Int32

Dim partCount, i, port As Int32

Dim ipData, buf, ipAddress As String

Dim parts(6) As Int32

Dim ch As Char

Dim s As Socket

Dim ep As IPEndPoint

 

SendCommand("PASV")

If (m_iRetValue <> 227) Then

MessageString = m_sReply

Throw New IOException(m_sReply.Substring(4))

End If

 

index1 = m_sReply.IndexOf("(")

index2 = m_sReply.IndexOf(")")

ipData = m_sReply.Substring(index1 + 1, index2 - index1 - 1)

 

len = ipData.Length

partCount = 0

buf = ""

 

For i = 0 To ((len - 1) And partCount <= 6)

ch = Char.Parse(ipData.Substring(i, 1))

If (Char.IsDigit(ch)) Then

buf += ch

ElseIf (ch <> ",") Then

MessageString = m_sReply

Throw New IOException("Malformed PASV reply: " & m_sReply)

End If

 

If ((ch = ",") Or (i + 1 = len)) Then

Try

parts(partCount) = Int32.Parse(buf)

partCount += 1

buf = ""

Catch ex As Exception

MessageString = m_sReply

Throw New IOException("Malformed PASV reply: " & m_sReply)

End Try

End If

Next

 

ipAddress = parts(0) & "." & parts(1) & "." & parts(2) & "." & parts(3)

 

' Make this call in VB.NET 2002. We would like to

' bitshift the number by 8 bits, so in VB.NET 2002 we

' multiply the number by 2 to the power of 8.

port = parts(4) * (2 ^ 8)

 

' Make this call and comment out the above line for

' VB.NET 2003.

'port = parts(4) << 8

 

' Determine the data port number.

port = port + parts(5)

 

s = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

ep = New IPEndPoint(Dns.Resolve(ipAddress).AddressList(0), port)

 

Try

s.Connect(ep)

Catch ex As Exception

MessageString = m_sReply

Throw New IOException("Can't connect to remote server")

End Try

 

Return s

End Function

 

#End Region

End Class

0 comentarios en total.

Pon un comentario:

Debes estar registrado para enviar comentarios.

Debes estar registrado para enviar comentarios. Hazlo, es un segundo! ;)
Deseas ir a la pagina de registro?. O, si ya estas registrado, a la de login?

Programando en .NET freelance web desarrollador programador autonomo .net framework microsoft aplicacion escritorio vb.net ASP.NET VB.NET C# DLL HTML JavaScript VBA VBScript CSS SQL Server sqlServer Access MySQL
Copyright: yoquierounblog