我用WINSOCK做了個FTP下載工具,每次運行的時候,第一次就能下載,但下載完畢之后,再重新下載就無法連接,但關閉行程重新打開又可以,請問是什么原因導致呢?謝謝
代碼如下:
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private wsFtpServerIP As String
Private wsFtpServerPort As String
Private wsFtpUserName As String
Private wsFtpPassword As String
Private wsFtpLocalFile As String
Private wsFtpLocalFileLen As Variant
Private wsFtpLocalFileMaxLen As Variant
Private wsFtpLocalNum As Long
Private wsFtpHostFile As String
Private wsGetDataStr As String
'是否打開Winsock用于下載
Public Function StartWinsock(ByVal tConnectWs As Winsock, ByVal tDownloadWs As Winsock, ByVal tHostFile As String, ByVal tLocalFile As String, ByVal tFtpIp As String, Optional ByVal tPort As String = "21", Optional ByVal tUserName As String = "anonymous", Optional ByVal tPw As String) As Boolean
Dim PathT As String
Dim FileT As String
Dim FileHaveLen As String
Dim tSplit() As String
Dim tStart As Boolean
'初始化內容
wsFtpServerIP = tFtpIp
wsFtpServerPort = tPort
wsFtpUserName = tUserName
wsFtpPassword = tPw
wsFtpHostFile = tHostFile
wsFtpLocalFile = tLocalFile
With tConnectWs
If .State = 0 Then '斷開重連
.RemoteHost = wsFtpServerIP
.RemotePort = wsFtpServerPort
.Connect
Do
If .State = 7 Then Exit Do
DoEvents
Loop
End If
.SendData "USER " & "anonymous" & vbCrLf '輸入賬號
Debug.Print "########################" & .State
Do
If .State = 7 Then
'If Len(wsGetDataStr) <= 0 Then
'.SendData "USER " & "anonymous" & vbCrLf '輸入賬號
'Else
tSplit() = Split(wsGetDataStr, Space(1), , vbTextCompare)
Select Case LCase(Left(wsGetDataStr, 3))
Case "220"
.SendData "USER " & "anonymous" & vbCrLf '輸入賬號
wsGetDataStr = ""
Case "331"
.SendData "PASS " & "" & vbCrLf '輸入密碼
wsGetDataStr = ""
Case "230"
.SendData "TYPE I" & vbCrLf '連接成功
wsGetDataStr = ""
Case "530"
.Close
wsGetDataStr = ""
'以下為連接成功后的操作
Case "200"
tConnectWs.SendData "PASV" & vbCrLf '修改為PASV模式
wsGetDataStr = ""
Case "227"
'獲取臨時埠和IP
Dim Tmp1, Tmp2, Tmp3, Tmp4
Dim TmpIp, TmpPort
Tmp1 = InStr(wsGetDataStr, Chr(40)) + 1
Tmp2 = InStrRev(wsGetDataStr, Chr(41))
Tmp3 = Mid(wsGetDataStr, Tmp1, Tmp2 - Tmp1)
Tmp4 = Split(Tmp3, ",")
TmpIp = Tmp4(0) & "." & Tmp4(1) & "." & Tmp4(2) & "." & Tmp4(3)
TmpPort = Tmp4(4) * 256 + Tmp4(5)
.SendData "PWD" & vbCrLf
wsGetDataStr = ""
Case "257" '用PWD回傳當前目錄
wsFtpHostFile = Replace(wsFtpHostFile, "\", "/")
PathT = Left(wsFtpHostFile, InStrRev(wsFtpHostFile, "/"))
'改變目錄
If tSplit(1) = "/" Then '如果是根目錄
.SendData "CWD " & PathT & vbCrLf
Else
.SendData "CWD /" & PathT & vbCrLf
End If
wsGetDataStr = ""
Case "250"
'獲取檔案長度
Debug.Print "wsFtpHostFile=" & wsFtpHostFile
FileT = Right(wsFtpHostFile, Len(wsFtpHostFile) - InStrRev(wsFtpHostFile, "/"))
tConnectWs.SendData "SIZE " & FileT & vbCrLf
wsGetDataStr = ""
Case "213"
'寫入檔案
Debug.Print "Len(wsGetDataStr)=" & Len(wsGetDataStr)
tSplit() = Split(wsGetDataStr, " ", , vbTextCompare)
wsFtpLocalFileMaxLen = Val(Replace(tSplit(1), vbCrLf, "", , , vbTextCompare))
wsFtpLocalNum = IIf(wsFtpLocalNum = 0, FreeFile(), wsFtpLocalNum)
Open wsFtpLocalFile For Binary Lock Write As #wsFtpLocalNum
If LOF(wsFtpLocalNum) > 0 Then
FileHaveLen = FileLen(wsFtpLocalFile)
Close #wsFtpLocalNum
Else
Close #wsFtpLocalNum
End If
tConnectWs.SendData "REST " & FileHaveLen & vbCrLf '不能去掉,否則檔案會繼續寫入
'資料下載部分
With tDownloadWs
If TmpIp <> .RemoteHost Then
.RemoteHost = TmpIp
.RemotePort = TmpPort
If .State = 7 Then .Close
.Connect
End If
End With
tConnectWs.SendData "RETR " & FileT & vbCrLf
tStart = True
wsFtpLocalNum = IIf(wsFtpLocalNum = 0, FreeFile(), wsFtpLocalNum)
Open wsFtpLocalFile For Binary Lock Write As #wsFtpLocalNum
wsGetDataStr = ""
Case "226"
Close #wsFtpLocalNum
'.SendData "QUIT" & vbCrLf
wsGetDataStr = ""
Exit Do
End Select
'wsGetDataStr = ""
Else
If LCase(Left(wsGetDataStr, 3)) = "221" Then '正式斷開
'If tStart = True Then
'StartWinsock = True
wsFtpLocalNum = 0
.Close
tDownloadWs.Close
Exit Do
'End If
End If
End If
DoEvents
Loop
MsgBox "fff"
End With
End Function
'連接WINSOCK在DataArrival發生的事件
Public Sub WsConnectDataArrival(ByVal tConnectWs As Winsock, ByVal tDownloadWs As Winsock)
With tConnectWs
If .State = 7 Then
.GetData wsGetDataStr
End If
End With
End Sub
'連接WINSOCK在DataArrival發生的事件
Public Sub WsDownloadDataArrival(ByVal tDownloadWs As Winsock)
Dim ByteData() As Byte
With tDownloadWs
If .State = 7 Then
.GetData ByteData(), vbByte
wsFtpLocalFileLen = LOF(wsFtpLocalNum) + 1
Put #wsFtpLocalNum, wsFtpLocalFileLen, ByteData()
End If
End With
End Sub
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/249190.html
標籤:控件
上一篇:Mayberry小鎮的管理 | 三種截然不同的領導風格 3M
下一篇:開題報告!!!
