Potresti usare la classe
WebRequestMethods.Ftp
ti espone tutti i metodi di un client ftp, sfortunatamente è presente dal framework 2.0 in poi. Nel framework 1.1 non è presente, puoi usare questa classe (l'ho scritta nel 2006), è abbastanza commentata
Imports System.Net
Imports System.Net.Sockets
Imports System.IO
Imports System.Text
Imports Microsoft.VisualBasic
Imports System.Runtime.Remoting.Messaging
#Region "Possibili risposte server Ftp microsoft"
'''''''''''1xx - Positive Preliminary Reply
'''''''''''These status codes indicate that an action has started successfully,
'''''''''''but the client expects another reply before it continues with a new command.
'''''''''''
#Region " "
#End Region
'''''''''''2xx - Positive Completion Reply
'''''''''''An action has successfully completed.
''''''''''' The client can execute a new command.
#Region " "
#End Region
'''''''''''3xx - Positive Intermediate Reply
'''''''''''The command was successful, but the server needs additional information
'''''''''''from the client to complete processing the request.
#Region " "
#End Region
'''''''''''4xx - Transient Negative Completion Reply
'''''''''''The command was not successful, but the error is temporary.
'''''''''''If the client retries the command, it may succeed.
#Region " "
#End Region
'''''''''''5xx - Permanent Negative Completion Reply
'''''''''''The command was not successful, and the error is permanent.
'''''''''''If the client retries the command, it receives the same error.
#End Region
#Region "Classe FtpFileInfo"
Public Class FtpFileInfo
Public Nome As String
Public Dimensione As Integer
Public Data As Date
End Class
#End Region
#Region "Classe Ftp"
Public Class clsMrpFTP
#Region "Variabili private"
Private Const ReceiveBufferSize As Integer = 30 * 1024 * 1024 '2147483647 '8192
Private priTcpClient As New TcpClient()
Private priTcpClient2 As New TcpClient()
Private intBytesRec As Integer
Private priServerAdd As IPAddress
Private priFtpPort As Integer = 21
Private priConnected As Boolean = False
Private priFtpResponce As String
Private readBuffer(ReceiveBufferSize) As Byte
#End Region
#Region "Proprietà classe Ftp"
'FTP Server IP
ReadOnly Property ServerAdd() As IPAddress
Get
ServerAdd = priServerAdd
End Get
End Property
'FTP Port
ReadOnly Property FtpPort() As Int32
Get
FtpPort = priFtpPort
End Get
End Property
'Connection State
ReadOnly Property Connected() As Boolean
Get
Connected = priConnected
End Get
End Property
'FTP Server return info
ReadOnly Property FtpResponce() As String
Get
FtpResponce = priFtpResponce
End Get
End Property
#End Region
#Region "Metodi classe ftp"
#Region "Costruttore"
Public Sub New()
BuildConnection(Dns.Resolve("localhost").AddressList(0), 21)
End Sub
' Nome server come indirizzo Ip xxx.xxx.xxx.
Public Sub New(ByVal ServerAdd As IPAddress, ByVal FtpPort As Int32)
BuildConnection(ServerAdd, FtpPort)
End Sub
' Nome server come indirizzo DNS
Public Sub New(ByVal ServerAdd As String, ByVal FtpPort As Int32)
Try
BuildConnection(Dns.Resolve(ServerAdd).AddressList(0), FtpPort)
Catch err As Exception
MsgBox(err.ToString())
Me.Dispose()
End Try
End Sub
#End Region
#Region "Distruttore"
Protected Sub Dispose()
If Not priConnected Then
Call Close()
End If
End Sub
#End Region
Public Delegate Sub DnsCallback(ByVal ar As IAsyncResult)
#Region "Metodi Private"
'Apre Connessione FTP
Private Sub BuildConnection(ByVal ServerAdd As IPAddress, ByVal FtpPort As Int32)
Dim strTemp As String
If FtpPort <= 0 Or FtpPort > 65535 Then
MsgBox("Port number out of 1~65535 !")
Exit Sub
End If
priServerAdd = ServerAdd
priFtpPort = FtpPort
Try
priTcpClient.Connect(ServerAdd, FtpPort)
AttendiRisposta()
strTemp = priFtpResponce
If strTemp.Substring(0, 4) <> "220 " Then
If strTemp.Substring(0, 3) = "220" Then
AttendiRisposta()
End If
End If
priConnected = True
Catch err As Exception
MsgBox("Errore nella Connessione " & vbCrLf & err.ToString())
End Try
End Sub
'Attende risposta server FTP
Private Function AttendiRisposta()
'Attende risposta su porta principale
Dim priBytes(1) As Byte
priFtpResponce = ""
While priTcpClient.GetStream.DataAvailable = False
Application.DoEvents()
End While
Do
'ReDim priBytes(ReceiveBufferSize)
intBytesRec = priTcpClient.GetStream.Read(priBytes, 0, 1)
priFtpResponce = priFtpResponce & Encoding.ASCII.GetString(priBytes, 0, intBytesRec)
Application.DoEvents()
Loop While priTcpClient.GetStream.DataAvailable
End Function
Private Function AttendiRisposta2()
'Attende risposta su porta secondaria
Dim priBytes(ReceiveBufferSize) As Byte
priFtpResponce = ""
Do
'ReDim priBytes(ReceiveBufferSize)
intBytesRec = priTcpClient2.GetStream.Read(priBytes, 0, ReceiveBufferSize)
priFtpResponce = priFtpResponce & Encoding.ASCII.GetString(priBytes, 0, intBytesRec)
Application.DoEvents()
Loop While priTcpClient2.GetStream.DataAvailable
End Function
Private Function AttendiRisposta2(ByVal FileOut As String)
'Attende risposta su porta secondaria e salva flusso su fileout
Dim fs As New FileStream(FileOut, FileAccess.Write)
Dim priBytes(ReceiveBufferSize) As Byte
While True
Do
' ReDim priBytes(0)
' ReDim priBytes(ReceiveBufferSize)
intBytesRec = priTcpClient2.GetStream.Read(priBytes, 0, ReceiveBufferSize)
'priFtpResponce = priFtpResponce & Encoding.ASCII.GetString(priBytes, 0, intBytesRec)
fs.Write(priBytes, 0, intBytesRec)
Application.DoEvents()
Loop While priTcpClient2.GetStream.DataAvailable
If priTcpClient.GetStream.DataAvailable Then
priFtpResponce = ""
Do
' ReDim priBytes(0)
' ReDim priBytes(ReceiveBufferSize)
intBytesRec = priTcpClient.GetStream.Read(priBytes, 0, ReceiveBufferSize)
priFtpResponce = priFtpResponce & Encoding.ASCII.GetString(priBytes, 0, intBytesRec)
Application.DoEvents()
Loop While priTcpClient.GetStream.DataAvailable
Exit While
End If
End While
fs.Flush()
fs.Close()
End Function
#End Region
#Region "Metodi Public"
' Chiude connessione FTP
Public Sub Close()
Dim priBytes(ReceiveBufferSize) As Byte
If priConnected Then
Try
priBytes = Encoding.ASCII.GetBytes("QUIT" & vbCrLf)
priTcpClient.GetStream.Write(priBytes, 0, priBytes.Length)
AttendiRisposta()
priTcpClient.Close()
Catch err As Exception
MsgBox(err.ToString())
Finally
priConnected = False
End Try
End If
End Sub
'Login server FTP
Public Function IdVerify(ByVal strID As String, ByVal strPW As String) As Boolean
Dim strTemp As String
Dim priBytes(ReceiveBufferSize) As Byte
If priConnected Then
'ID
priBytes = Encoding.ASCII.GetBytes("USER " & strID & vbCrLf)
priTcpClient.GetStream.Write(priBytes, 0, priBytes.Length)
AttendiRisposta()
strTemp = priFtpResponce
If strTemp.Substring(0, 4) <> "331 " Then
priFtpResponce = strTemp ' MsgBox(strTemp)
Exit Function
End If
'password
priBytes = Encoding.ASCII.GetBytes("PASS " & strPW & vbCrLf)
priTcpClient.GetStream.Write(priBytes, 0, priBytes.Length)
AttendiRisposta()
strTemp = priFtpResponce
If strTemp.Substring(0, 4) <> "230 " Then
Return False
Exit Function
End If
Return True
End If
End Function
'Richiede elenco files in directory remota
'Possibile chiamata doppia (function con Overloads )
Public Overloads Function DirList(ByVal strFile As String) As String
Dim intPort As Int32
Dim strTemp As String
Dim priBytes(ReceiveBufferSize) As Byte
If priConnected Then
Try
intPort = cmdPasv2Port()
priTcpClient2 = New TcpClient()
priTcpClient2.Connect(priServerAdd.ToString, intPort)
priBytes = Encoding.ASCII.GetBytes("LIST -aL " & strFile & vbCrLf)
priTcpClient.GetStream.Write(priBytes, 0, priBytes.Length)
AttendiRisposta()
Application.DoEvents()
AttendiRisposta2()
DirList = priFtpResponce
Application.DoEvents()
AttendiRisposta()
priTcpClient2.Close()
strTemp = priFtpResponce
If strTemp.Substring(0, 4) <> "150 " Then
priFtpResponce = strTemp ' MsgBox(strTemp)
End If
Catch err As Exception
MsgBox(err.ToString())
End Try
End If
End Function
Public Overloads Function DirList() As String
Dim intPort As Int32
Dim priSM As New MemoryStream()
Dim strTemp As String
Dim priBytes(ReceiveBufferSize) As Byte
If priConnected Then
Try
intPort = cmdPasv2Port()
priTcpClient2.Connect(priServerAdd.ToString, intPort)
priBytes = Encoding.ASCII.GetBytes("LIST -aL" & vbCrLf)
priTcpClient.GetStream.Write(priBytes, 0, priBytes.Length)
AttendiRisposta()
Application.DoEvents()
AttendiRisposta2()
DirList = strTemp
AttendiRisposta()
priTcpClient2.Close()
strTemp = priFtpResponce
If strTemp.Substring(0, 4) <> "150 " Then
priFtpResponce = strTemp ' MsgBox(strTemp)
End If
Catch err As Exception
MsgBox(err.ToString())
End Try
End If
End Function
' Invia richiesta connessione su porta secondaria
'Formato x0,x1,x2,x3,a,b
'PORT =(256 x a) + b
Public Function cmdPasv2Port() As Int32
Dim i, j As Int32
Dim strTemp As String
Dim priBytes(ReceiveBufferSize) As Byte
If priConnected Then
'
priBytes = Encoding.ASCII.GetBytes("PASV" & vbCrLf)
Try
priTcpClient.GetStream.Write(priBytes, 0, priBytes.Length)
AttendiRisposta()
strTemp = priFtpResponce
strTemp = priFtpResponce
Dim arr() As Char = {".", ")", vbCr, vbLf}
Dim temp() As String = strTemp.Trim(arr).Split(",")
cmdPasv2Port = 256 * CInt(temp(4)) + CInt(temp(5))
Catch err As Exception
MsgBox(err.ToString())
End Try
End If
End Function
'Invia comando FTP
Public Function FtpCommand(ByVal strCommand As String) As String
Dim priBytes(ReceiveBufferSize) As Byte
If priConnected Then
Try
priBytes = Encoding.ASCII.GetBytes(strCommand & vbCrLf)
priTcpClient.GetStream.Write(priBytes, 0, priBytes.Length)
AttendiRisposta()
FtpCommand = priFtpResponce
Catch err As Exception
MsgBox(err.ToString())
End Try
End If
End Function
'Richiedi Info sul file
Public Function FtpGetFileInfo(ByVal strFile As String) As FtpFileInfo
Dim strTemp As String
Dim temp() As String
Dim tmpFtpFileInfo As New FtpFileInfo()
strTemp = DirList(strFile)
If priFtpResponce.StartsWith("5") Then
Return Nothing
Exit Function
End If
While strTemp.Replace(" ", " ") <> strTemp
strTemp = strTemp.Replace(" ", " ")
End While
temp = strTemp.Split(" ")
tmpFtpFileInfo.Dimensione = temp(2).Trim(vbCrLf)
tmpFtpFileInfo.Nome = temp(3).Trim(vbCrLf)
Return tmpFtpFileInfo
Exit Function
End Function
'Avvia Download file remoto
'Possibile chiamata doppia (function conOverloads)
' se indicato file di destinazione ritorna True / False
' se non indcato ritorna una stringa
Public Overloads Function FtpGetFile(ByVal strFile As String, ByVal strFileDestinazione As String) As Boolean
'Download strFile in destinazione strFileDestinazione
Dim intPort As Int32
Dim strTemp As String
Dim i, j, i1 As Int16
'Dim Dimensione As Long
If priConnected Then
' Try
'Dimensione = FtpGetFileInfo(strFile).Dimensione
FtpCommand("TYPE I")
intPort = cmdPasv2Port()
priTcpClient2 = New TcpClient
priTcpClient2.Connect(priServerAdd.ToString, intPort)
FtpCommand("RETR " & strFile)
If priFtpResponce.StartsWith("5") Then
Return False
Exit Function
End If
AttendiRisposta2(strFileDestinazione)
Return True
' Catch err As Exception
' MsgBox(Err.ToString())
' End Try
End If
End Function
' Ritorna il file in una stringa
Public Overloads Function FtpGetFile(ByVal strFile As String) As String
Dim intPort As Int32
Dim strTemp As String
Dim i, j, i1 As Int16
If priConnected Then
Try
FtpCommand("TYPE I")
intPort = cmdPasv2Port()
priTcpClient2 = New TcpClient
priTcpClient2.Connect(priServerAdd.ToString, intPort)
FtpCommand("RETR " & strFile)
If priFtpResponce.StartsWith("5") Then
Return ""
Exit Function
End If
AttendiRisposta()
priFtpResponce = strTemp
AttendiRisposta2()
strTemp = priFtpResponce
'AttendiRisposta()
Return strTemp
Catch err As Exception
MsgBox(err.ToString())
End Try
End If
End Function
'Avvia Upload file remoto
Public Overloads Function FtpPutFile(ByVal FileIn As String, ByVal FileOut As String) As Boolean
'Upload strFile in directory corrente
Dim intPort As Int32
Dim strTemp As String
Dim i, j, i1 As Int16
'Dim Dimensione As Long
Dim priTcpClient2 As New TcpClient
If priConnected Then
Try
'Dimensione = FtpGetFileInfo(strFile).Dimensione
FtpCommand("TYPE I")
intPort = cmdPasv2Port()
priTcpClient2.Connect(priServerAdd.ToString, intPort)
FtpCommand("STOR " & FileOut)
If priFtpResponce.StartsWith("5") Then
Return False
Exit Function
End If
' AttendiRisposta2(strFile)
Dim fs As New FileStream(FileIn, FileMode.Open, FileAccess.Read)
Dim priBytes(ReceiveBufferSize) As Byte
Dim TotBytesRead As Long = FileLen(FileIn)
Dim BytesToRead As Long
Do While TotBytesRead > 0
BytesToRead = Math.Min(ReceiveBufferSize, CInt(TotBytesRead))
intBytesRec = fs.Read(priBytes, 0, BytesToRead)
priTcpClient2.GetStream.Write(priBytes, 0, intBytesRec)
Application.DoEvents()
TotBytesRead -= intBytesRec
Loop
priTcpClient2.Close()
Application.DoEvents()
fs.Close()
AttendiRisposta()
Return True
Catch err As Exception
MsgBox(err.ToString())
End Try
End If
End Function
#End Region
#End Region
End Class
#End Region