FTP上传、下载、获得文件列表(socket)

来源:互联网 发布:dota2 lol 知乎 编辑:程序博客网 时间:2024/05/28 09:33

网上copy的代码,自己修改了一点后应用在自己的项目里了。 谢谢写这段代码的老兄!

 

 

     Public Class MyFTP 'FTP相关操作
        Public Obj_ClientSocket As Socket
        Public Str_Domain As String    'ftp服务器地址
        Public Str_User As String      'ftp登陆帐号
        Public Str_Password As String    'ftp登陆密码
        Public Int_RemotePort As Integer       'ftp服务器端口
        Public Login As Boolean  '是否登陆
        Private Int_Reply, Int_Bytes As Int32
        Private Str_Message, Str_Reply As String
        Private Byte_Buffer(BLOCK_SIZE) As Byte
        Private ASCII As Encoding = Encoding.ASCII


#Region "登陆FTP"
        Public Function Logined() As Boolean
            Obj_ClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            Dim x_lob As New IPEndPoint(Dns.GetHostEntry(Str_Domain).AddressList(0), Int_RemotePort)
            Try
                Obj_ClientSocket.Connect(x_lob)
            Catch ex As Exception
                System.Threading.Thread.Sleep(500)
            End Try
            Str_Message = ""
            Str_Reply = ServerReply()
            Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))
            If (Int_Reply <> 220) Then
                System.Threading.Thread.Sleep(500) : Logined()
            End If

            SendCommand("USER " & Str_User)
            Str_Reply = ServerReply(True)
            Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))
            If (Not (Int_Reply = 331 Or Int_Reply = 230)) Then
                Return False
            End If

            If (Int_Reply <> 230) Then
                SendCommand("PASS " & Str_Password)
                Str_Reply = ServerReply(True)
                Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))
                If (Not (Int_Reply = 230 Or Int_Reply = 202)) Then
                    Return False
                End If
            End If
            Return True
        End Function
#End Region

#Region "FTP答复"
        Private Function ServerReply(Optional ByVal Bool_Clear As Boolean = False) As String
            Dim Sep As Char = ControlChars.Lf
            Dim Arr_Msg() As String
            If (Bool_Clear) Then
                Str_Message = ""
            End If
            Do While (True)
                Try
                    Array.Clear(Byte_Buffer, 0, BLOCK_SIZE)
                    Int_Bytes = Obj_ClientSocket.Receive(Byte_Buffer, Byte_Buffer.Length, 0)
                    Str_Message += ASCII.GetString(Byte_Buffer, 0, Int_Bytes)
                    If (Int_Bytes < Byte_Buffer.Length) Then
                        Exit Do
                    End If
                Catch ex As Exception
                    Return ex.Message
                End Try
            Loop
            Arr_Msg = Str_Message.Split(Sep)
            If (Str_Message.Length > 2) Then
                Str_Message = Arr_Msg(Arr_Msg.Length - 2)
            Else
                Str_Message = Arr_Msg(0)
            End If
            'Try
            '    File.AppendAllText("C:/FTP_Reply.txt", Now & ":" & Str_Message & vbCrLf)
            'Catch ex As Exception
            'End Try
            If Str_Message.Length < 4 Then System.Threading.Thread.Sleep(500) : Return ServerReply(True)
            If (Not (Str_Message.Substring(3, 1).Equals(" "))) Then
                Return ServerReply(True)
            End If
            Return Str_Message
        End Function
#End Region

#Region "发送ftp命令"
        Public Sub SendCommand(ByVal Str_Command As String)
            Try
                Str_Command = Str_Command & ControlChars.CrLf
                Dim cmdbytes As Byte() = ASCII.GetBytes(Str_Command)
                Obj_ClientSocket.Send(cmdbytes, cmdbytes.Length, 0)
            Catch ex As Exception
                System.Threading.Thread.Sleep(500) : SendCommand(Str_Command)
            End Try
        End Sub
#End Region

#Region "上传文件"
        Public Function UploadFile(ByVal Str_LocalFileName As String, ByVal Bool_Resume As Boolean, ByVal SavePath As String) As String
            'str_localfilename 文件完整路径
            'bool_resume 是否断点续传
            Dim LobSocket As Socket
            Dim offset As Long
            Dim input As FileStream
            Dim bFileNotFound As Boolean
            If Not Login Then Login = Logined()
            LobSocket = CreateDataSocket()
            offset = 0
            If (Bool_Resume) Then
                Try
                    SetBinaryMode(True)
                    offset = GetFileSize(Str_LocalFileName)
                Catch ex As Exception
                    offset = 0
                End Try
            End If
            If (offset > 0) Then
                SendCommand("REST " & offset)
                If (Int_Reply <> 350) Then
                    offset = 0
                End If
            End If
            SendCommand("STOR " & "/" & SavePath & "/" & Path.GetFileName(Str_LocalFileName))
            Str_Reply = ServerReply(True)
            If Str_Reply.Length < 4 Then Return "返回数据错误 " & Str_Reply
            Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))
            If (Not (Int_Reply = 125 Or Int_Reply = 150)) Then
                Return (Str_Reply.Substring(4))
            End If
            bFileNotFound = False
            If (File.Exists(Str_LocalFileName)) Then
                input = New FileStream(Str_LocalFileName, FileMode.Open)
                If (offset <> 0) Then
                    input.Seek(offset, SeekOrigin.Begin)
                End If
                Int_Bytes = input.Read(Byte_Buffer, 0, Byte_Buffer.Length)
                Do While (Int_Bytes > 0)
                    LobSocket.Send(Byte_Buffer, Int_Bytes, 0)
                    Int_Bytes = input.Read(Byte_Buffer, 0, Byte_Buffer.Length)
                Loop
                input.Close()
            Else
                bFileNotFound = True
            End If
            If (LobSocket.Connected) Then
                LobSocket.Close()
            End If
            If (bFileNotFound) Then
                Return (Str_LocalFileName & "文件未找到,无法上传")
            End If
            Str_Reply = ServerReply(True)
            Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))
            If (Not (Int_Reply = 226 Or Int_Reply = 250)) Then
                Return (Str_Reply.Substring(4))
            End If
            Return "OK"
        End Function
#End Region

#Region "获取文件大小"
        Public Function GetFileSize(ByVal sFileName As String) As Long
            Dim size As Long
            SendCommand("SIZE " & sFileName)
            size = 0
            Str_Reply = ServerReply(True)
            If Str_Reply.Length < 4 Then System.Threading.Thread.Sleep(500) : GetFileSize(sFileName)
            Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))
            If (Int_Reply = 213) Then
                size = Int64.Parse(Str_Reply.Substring(4))
            Else
                System.Threading.Thread.Sleep(500)
            End If
            Return size
        End Function
#End Region

#Region "下载文件"
        Public Function DownloadFile(ByVal Str_RemoteFileName As String, ByVal Str_LocalFileName As String, ByVal Bool_Resume As Boolean) As String
            'str_RemoteFileName FTP文件名
            'str_LocalFileName 本地文件路径
            'rool_Resume 是否断点续传
            Dim Data_St As Stream
            Dim output As FileStream
            Dim LobSocket As Socket
            Dim offset, npos As Long
            If (Not Logined()) Then
                Logined()
            End If
            SetBinaryMode(True)
            If (Str_LocalFileName.Equals("")) Then
                Str_LocalFileName = Str_RemoteFileName
            End If

            If (Not (File.Exists(Str_LocalFileName))) Then
                Data_St = File.Create(Str_LocalFileName)
                Data_St.Close()
            End If

            Try
                output = New FileStream(Str_LocalFileName, FileMode.Open)

            Catch ex As Exception
                Return ex.Message
            End Try
            LobSocket = CreateDataSocket()
            offset = 0

            If (Bool_Resume) Then
                offset = output.Length

                If (offset > 0) Then
                    SendCommand("REST " & offset)
                    Str_Reply = ServerReply(True)
                    Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))
                    If (Int_Reply <> 350) Then
                        offset = 0
                    End If
                End If

                If (offset > 0) Then
                    npos = output.Seek(offset, SeekOrigin.Begin)
                End If
            End If

            SendCommand("RETR " & Str_RemoteFileName)
            Str_Reply = ServerReply(True)
            Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))

            If (Not (Int_Reply = 150 Or Int_Reply = 125)) Then
                Return (Str_Reply.Substring(4))
            End If

            Do While (True)
                Array.Clear(Byte_Buffer, 0, Byte_Buffer.Length)
                Int_Bytes = LobSocket.Receive(Byte_Buffer, Byte_Buffer.Length, 0)
                output.Write(Byte_Buffer, 0, Int_Bytes)
                If (Int_Bytes <= 0) Then
                    Exit Do
                End If
            Loop

            output.Close()
            If (LobSocket.Connected) Then
                LobSocket.Close()
            End If

            Str_Reply = ServerReply(True)
            Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))
            If (Not (Int_Reply = 226 Or Int_Reply = 250)) Then
                Return (Str_Reply.Substring(4))
            End If
            Return "OK"
        End Function
#End Region

#Region "建立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")
            Str_Reply = ServerReply(True)
            Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))
            If (Int_Reply <> 227) Then
                'MsgBox(Str_Reply.Substring(4))
            End If
            index1 = Str_Reply.IndexOf("(")
            index2 = Str_Reply.IndexOf(")")
            If index1 = -1 Or index2 = -1 Then Return Nothing
            ipData = Str_Reply.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
                    'MsgBox(Str_Reply)
                End If

                If ((ch = ",") Or (i + 1 = len)) Then
                    Try
                        parts(partCount) = Int32.Parse(buf)
                        partCount += 1
                        buf = ""
                    Catch ex As Exception
                        'MsgBox(Str_Reply)
                    End Try
                End If
            Next
            ipAddress = parts(0) & "." & parts(1) & "." & parts(2) & "." & parts(3)
            port = parts(4) * (2 ^ 8)
            port = port + parts(5)
            s = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            ep = New IPEndPoint(Dns.GetHostEntry(ipAddress).AddressList(0), port)
            Try
                s.Connect(ep)
            Catch ex As Exception
                System.Threading.Thread.Sleep(500) : s.Connect(ep)
            End Try
            Return s
        End Function
#End Region

#Region "设置访问模式"
        Public Sub SetBinaryMode(ByVal bMode As Boolean)
            If (bMode) Then
                SendCommand("TYPE I")
            Else
                SendCommand("TYPE A")
            End If
            Str_Reply = ServerReply(True)
            If Str_Reply.Length < 4 Then System.Threading.Thread.Sleep(500) : SetBinaryMode(bMode)
            Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))
            If (Int_Reply <> 200) Then
                'MsgBox(Str_Reply.Substring(4))
            End If
        End Sub
#End Region

#Region "获取指定目录文件列表"
        Public Function GetFileList(ByVal path As String) As String
            If Not Login Then Logined()
            Randomize()
            Dim tempfile As String = Format(Rnd() * 100, "0.00")
            Dim output As FileStream = New FileStream(Application.StartupPath & "/" & tempfile, FileMode.OpenOrCreate)
            Dim LobSocket As Socket
            Dim offset As Long
            SetBinaryMode(True)
            LobSocket = CreateDataSocket()
            offset = 0
            SendCommand("CWD " & path)
            SendCommand("LIST")
            Str_Reply = ServerReply(True)
            Int_Reply = Int32.Parse(Str_Reply.Substring(0, 3))

            Do While (True)
                Array.Clear(Byte_Buffer, 0, Byte_Buffer.Length)
                Int_Bytes = LobSocket.Receive(Byte_Buffer, Byte_Buffer.Length, 0)
                output.Write(Byte_Buffer, 0, Int_Bytes)
                If (Int_Bytes <= 0) Then
                    Exit Do
                End If
            Loop
            output.Close()
            If (LobSocket.Connected) Then
                LobSocket.Close()
            End If
            Dim setfile As String = Application.StartupPath & "/" & tempfile
            Dim line As String = ""
            Dim sr As StreamReader = New StreamReader(setfile, System.Text.Encoding.Default)
            Dim returnstr As String = ""
            Dim i As Integer = 0
            Do While sr.Peek() > 0
                line = sr.ReadLine()
                returnstr = returnstr & line.Substring(line.LastIndexOf(" ") + 1)
                If line.IndexOf("<DIR>") <> -1 Then
                    returnstr = returnstr & "<D>;"
                Else
                    returnstr = returnstr & "<F>;"
                End If
            Loop
            sr.Close()
            File.Delete(setfile)
            Return returnstr
        End Function

#End Region

    End Class

原创粉丝点击