⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cftpconnection.cls

📁 用vb开发的ftp客服端
💻 CLS
📖 第 1 页 / 共 5 页
字号:
'********************************************************************************

On Error GoTo Connect_Err_Handler

Dim strData     As String

m_strWinsockBuffer = ""
m_bBusy = True

If Len(m_varFtpServer) > 0 Then
    With wscControl
        .Close
        .LocalPort = 0
        .Connect m_varFtpServer, 21
        m_objTimeOut.StartTimer
        Do
            DoEvents
            '
            If m_objTimeOut.Timeout Then
                m_LastError = ERROR_FTP_USER_TIMEOUT
                Exit Do
            End If
            '
            If .State = sckConnected Then
                m_objTimeOut.StopTimer
                RaiseEvent StateChanged(FTP_CONNECTION_CONNECTED)
                m_objTimeOut.StartTimer
                Do
                    DoEvents
                    '
                    If m_objTimeOut.Timeout Then
                        m_LastError = ERROR_FTP_USER_TIMEOUT
                        Exit Do
                    End If
                    '
                    If Len(m_strWinsockBuffer) > (RESPONSE_CODE_LENGHT - 1) Then
                        strData = m_strWinsockBuffer
                        m_strWinsockBuffer = ""
                        Exit Do
                    End If
                Loop
                m_objTimeOut.StopTimer
                Select Case GetResponseCode(strData)
                    Case FTP_RESPONSE_SERVICE_READY_FOR_NEW_USER
                        Select Case ProcessUSERCommand
                            Case FTP_RESPONSE_USER_LOGGED_IN
                                Connect = True
                            Case FTP_RESPONSE_USER_NAME_OK_NEED_PASSWORD
                                If ProcessPASSCommand = FTP_RESPONSE_USER_LOGGED_IN Then
                                    Connect = True
                                End If
                        End Select
                        'Get working directory
                        If Connect Then
                            Call ProcessPWDCommand
                        End If
                    Case FTP_RESPONSE_SERVICE_READY_IN_MINUTES
                        '120 Service ready in nnn minutes.
                        m_LastError = ERROR_FTP_PROTOCOL_SERVICE_READY_IN_MINUTES
                    Case FTP_RESPONSE_SERVICE_NOT_AVAILABLE_CLOSING_CONTROL_CONNECTION
                        '421 Service not available, closing control connection.
                        m_LastError = ERROR_FTP_PROTOCOL_SERVICE_NOT_AVAILABLE_CLOSING_CONTROL_CONNECTION
                End Select
                Exit Do
            ElseIf .State = sckConnectAborted Then
                m_LastError = ERROR_FTP_WINSOCK_ConnectAborted
            ElseIf .State = sckResolvingHost Then
                RaiseEvent StateChanged(FTP_CONNECTION_RESOLVING_HOST)
            ElseIf .State = sckHostResolved Then
                RaiseEvent StateChanged(FTP_CONNECTION_HOST_RESOLVED)
            End If
        Loop
        m_objTimeOut.StopTimer
    End With
Else
    'raise error
    Connect = False
    Exit Function
End If

Exit_Label:
    If Connect Then RaiseEvent StateChanged(FTP_USER_LOGGED)
    m_bBusy = False
    Exit Function

Connect_Err_Handler:
    If Not ProcessWinsockError(Err.Number, Err.Description) Then
        Err.Raise vbObjectError + 1000 + Err.Number, "CFtpConnection.Connect", Err.Description
    End If
    GoTo Exit_Label
    
End Function

Private Sub Class_Initialize()

    Set wscControl = New MSWinsockLib.Winsock
    Set wscData = New MSWinsockLib.Winsock
    Set m_objTimeOut = New CTimeout

End Sub

Private Function GetResponseCode(strResponse As String) As Integer

    If Len(strResponse) > (RESPONSE_CODE_LENGHT - 1) Then
        GetResponseCode = CInt(Left$(strResponse, 3))
    End If
        
End Function

Private Function ProcessUSERCommand() As FTP_RESPONSE_CODES

    Dim strData     As String
    
    On Error GoTo ProcessUSERCommand_Err_Handler
    
    RaiseEvent StateChanged(FTP_CONNECTION_AUTHENTICATION)

    m_strUserName = IIf(Len(m_strUserName) > 0, m_strUserName, "anonymous")
    
    If Len(m_strPassword) = 0 Then
        If m_strUserName = "anonymous" Then
            m_strPassword = "guest@unknown.com"
        Else
            'raise error
            Exit Function
        End If
    End If
    
    wscControl.SendData "USER " & m_strUserName & vbCrLf
    Debug.Print "USER " & m_strUserName
    
    m_objTimeOut.StartTimer
    Do
        DoEvents
        '
        If m_objTimeOut.Timeout Then
            m_LastError = ERROR_FTP_USER_TIMEOUT
            Exit Do
        End If
        '
        If Len(m_strWinsockBuffer) > RESPONSE_CODE_LENGHT Then
            strData = m_strWinsockBuffer
            m_strWinsockBuffer = ""
            Exit Do
        End If
    Loop
    m_objTimeOut.StopTimer
    
    Select Case GetResponseCode(strData)
        Case FTP_RESPONSE_USER_LOGGED_IN
            ProcessUSERCommand = FTP_RESPONSE_USER_LOGGED_IN
        Case FTP_RESPONSE_USER_NAME_OK_NEED_PASSWORD
            ProcessUSERCommand = FTP_RESPONSE_USER_NAME_OK_NEED_PASSWORD
        Case Else
            ProcessFtpResponse GetResponseCode(strData)
    End Select
    
Exit_Label:
    Exit Function

ProcessUSERCommand_Err_Handler:
    If Not ProcessWinsockError(Err.Number, Err.Description) Then
        Err.Raise vbObjectError + 1000 + Err.Number, "CFtpConnection.ProcessUSERCommand", Err.Description
    End If
    GoTo Exit_Label
    
End Function

Private Function ProcessPASSCommand() As FTP_RESPONSE_CODES

    Dim strResponse As String
    Dim strData     As String
    '
    On Error GoTo ProcessPASSCommand_Err_Handler

    wscControl.SendData "PASS " & m_strPassword & vbCrLf
    Debug.Print "PASS " & m_strPassword
    
    m_objTimeOut.StartTimer
    Do
        DoEvents
        '
        If m_objTimeOut.Timeout Then
            m_LastError = ERROR_FTP_USER_TIMEOUT
            Exit Do
        End If
        '
        If Len(m_strWinsockBuffer) > RESPONSE_CODE_LENGHT Then
            strData = m_strWinsockBuffer
            Exit Do
        End If
    Loop
    m_objTimeOut.StopTimer

    If GetResponseCode(strData) = FTP_RESPONSE_USER_LOGGED_IN Then
        Do
            DoEvents
            If InStr(1, m_strWinsockBuffer, "230 ") > 0 Then
                ProcessPASSCommand = FTP_RESPONSE_USER_LOGGED_IN
                m_strWinsockBuffer = ""
                Exit Function
            End If
        Loop
    Else
        ProcessFtpResponse GetResponseCode(strData)
    End If
    ProcessPASSCommand = GetResponseCode(strData)
    
Exit_Label:
    Exit Function

ProcessPASSCommand_Err_Handler:
    If Not ProcessWinsockError(Err.Number, Err.Description) Then
        Err.Raise vbObjectError + 1000 + Err.Number, "CFtpConnection.ProcessPASSCommand", Err.Description
    End If
    GoTo Exit_Label
    
End Function

Private Function ProcessPWDCommand() As Boolean

    Dim strResponse As String
    Dim strData     As String
    
    On Error GoTo ProcessPWDCommand_Err_Handler

    wscControl.SendData "PWD" & vbCrLf
    Debug.Print "PWD"
    
    m_objTimeOut.StartTimer
    Do
        DoEvents
        '
        If m_objTimeOut.Timeout Then
            m_LastError = ERROR_FTP_USER_TIMEOUT
            Exit Do
        End If
        '
        If InStr(1, m_strWinsockBuffer, vbCrLf) > 0 Then
            strData = m_strWinsockBuffer
            m_strWinsockBuffer = ""
            Exit Do
        End If
    Loop
    m_objTimeOut.StopTimer

    If GetResponseCode(strData) = FTP_RESPONSE_PATHNAME_CREATED Then
        Dim intPosA As Integer, intPosB As Integer
        intPosA = InStr(1, strData, Chr$(34)) + 1
        intPosB = InStr(intPosA, strData, Chr$(34))
        If intPosA > 1 And intPosB > 0 Then
            m_strCurrentDirectory = Mid$(strData, intPosA, intPosB - intPosA)
            ProcessPWDCommand = True
        Else
            'raise error - unknown response format
        End If
    Else
        ProcessFtpResponse GetResponseCode(strData)
    End If
    
Exit_Label:
    Exit Function

ProcessPWDCommand_Err_Handler:
    If Not ProcessWinsockError(Err.Number, Err.Description) Then
        Err.Raise vbObjectError + 1000 + Err.Number, "CFtpConnection.ProcessPWDCommand", Err.Description
    End If
    GoTo Exit_Label
        
End Function

Private Sub Class_Terminate()
    
    Call BreakeConnection
    Set wscData = Nothing
    Set wscControl = Nothing
    
    m_objTimeOut.StopTimer
    Set m_objTimeOut = Nothing
    
End Sub

Private Sub wscControl_DataArrival(ByVal bytesTotal As Long)
    
    Dim strData As String
    
    wscControl.GetData strData
    m_strWinsockBuffer = m_strWinsockBuffer & strData
    m_strLastServerResponse = strData
    m_objTimeOut.Reset
    
    
    If GetResponseCode(strData) = 426 Then
        If m_bTransferInProgress Or m_bUploadFile Then
            wscData.Close
            Close m_intLocalFileID
            m_strDataBuffer = ""
            m_lDownloadedBytes = 0
            m_lUploadedBytes = 0
            m_bTransferInProgress = False
            m_bUploadFile = False
            m_bFileIsOpened = False
        End If
        wscControl.Close
        m_bBusy = False
    End If
    
    Debug.Print Left(strData, Len(strData) - 2)
    
End Sub

Private Function ProcessPORTCommand() As Boolean

    Dim intPort         As Integer
    Dim strIPAddress    As String
    Dim colIPAddresses  As New Collection
    Dim strSend         As String
    Dim strData         As String
    
    On Error Resume Next
    
    RaiseEvent StateChanged(FTP_ESTABLISHING_DATA_CONNECTION)
    
    Do
        intPort = GetFreePort
        If wscData.State <> sckClosed Then wscData.Close
        wscData.LocalPort = intPort
        wscData.Listen
        If Not Err Then Exit Do
    Loop
    
    On Error GoTo ProcessPORTCommand_Err_Handler
    '
    strIPAddress = CStr(wscControl.LocalIP)
    '
    strSend = "PORT " & Replace(strIPAddress, ".", ",")
    strSend = strSend & "," & intPort \ 256 & "," & (intPort Mod 256)
    '
    strSend = strSend & vbCrLf
    '
    wscControl.SendData strSend
    Debug.Print Left(strSend, Len(strSend) - 2)
    
    m_objTimeOut.StartTimer
    Do
        DoEvents
        '
        If m_objTimeOut.Timeout Then
            m_LastError = ERROR_FTP_USER_TIMEOUT
            Exit Do
        End If
        '
        If InStr(1, m_strWinsockBuffer, vbCrLf) > 0 Then
            strData = m_strWinsockBuffer
            m_strWinsockBuffer = ""
            Exit Do
        End If
    Loop
    m_objTimeOut.StopTimer
    
    If GetResponseCode(strData) = FTP_RESPONSE_COMMAND_OK Then
        ProcessPORTCommand = True
        RaiseEvent StateChanged(FTP_DATA_CONNECTION_ESTABLISHED)
    Else
        ProcessFtpResponse GetResponseCode(strData)
    End If
    
Exit_Label:
    Exit Function

ProcessPORTCommand_Err_Handler:
    If Not ProcessWinsockError(Err.Number, Err.Description) Then
        Err.Raise vbObjectError + 1000 + Err.Number, "CFtpConnection.ProcessPORTCommand", Err.Description
    End If
    GoTo Exit_Label
        
End Function

Private Function GetFreePort() As Integer
    
    Static intPort As Integer
    
    If intPort = 0 Then
        intPort = 1100
    Else
        intPort = intPort + 1
    End If
    
    GetFreePort = intPort
    
End Function

Private Sub wscData_ConnectionRequest(ByVal requestID As Long)
    
    If wscData.State <> sckClosed Then wscData.Close
    
    wscData.Accept (requestID)
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -