2009-10-04 95 views
3

我想使用Winsock來下載一些文件並保存它們。 在我的情況下,我有一個MSHFlexGrid 2列:一個與URL和另一個「路徑+文件名」(其中文件將被保存)。 我通過遍歷所有的行調用一個函數:Winsock下載文件 - vb6

Public Function DownloadSock(ArqURL As String, ArqDestino As String) As Boolean 
'ArqURL is the file URL 
'ArqDestino is where the downloaded file is going to be stored, in my hard disc 

Dim arquivo() As Byte 
Dim ficheiroID As Integer 

ficheiroID = FreeFile 
On Error GoTo Trata_erro 
Open ArqDestino For Binary Access Write As #ficheiroID 


Me.Winsock1.Connect ArqURL, 80 
Me.Winsock1.GetData arquivo() 
Put #ficheiroID, , arquivo() 

Close #ficheiroID 

DownloadSock = True 


Exit Function 

Trata_erro: 

    MDIForm1.Text1 = MDIForm1.Text1 & "Error! " & Err.Number & Err.Description & " - " & Err.Source & " - URL: " & ArqURL & " - Destino: " & ArqDestino & vbNewLine 
    DownloadSock = False 

End Function 

我得到這個錯誤

40006:錯誤的協議或連接 狀態所要求的交易或 要求

我在做什麼錯?

謝謝

回答

2

您是否檢查了這個Microsoft Support page?它表示Winsock控件中存在一個錯誤,該修補程序可能會有所幫助。

另一件事是嘗試以確保您的Winsock連接是嘗試讀取/發送數據之前開放的,如果它被關閉,重新打開一個新的連接:

if winsock.state=9 ' error state 
    winsock.close 
    while winsock.state<>0 ' closed state 
    doEvents 
    wend ' you need a while loop, because it doesn't close "immediately". 
end if 
' now you reopen it, or do whatever else you need 

您也可能會考慮更改您的連接代碼如下:

With Winsock1 
     If .State <> sckClosed Then .Close 
     .RemoteHost = ArqURL 
     .RemotePort = 80 
     .Connect 
End With 

最後一件事。檢查出使用Winsock控件的this post

+1

這種方法將保持一切異步,同時避免需要調用'DoEvents'等待'Winsock.State'來改變。在處理由使用它的代碼造成的太多難以調試的問題之後,我對「DoEvents」特別謹慎,所以我傾向於不惜一切代價避免它,即使看起來像實現一個簡單的方法忙等待循環。 – 2009-10-05 05:22:59

1

我想你已經高估了Winsock控件的威力。您不能只使用Winsock的GetData方法來獲取並獲取文件。客戶端應用程序和服務器端的其他應用程序之間必須有活動連接。建立連接後,此服務器應用程序將數據提供給您的應用程序,Winsock的DataArrival事件將觸發,然後您可以使用GetData方法來檢索它。你的代碼應該看起來更像是這樣的:

Public Sub DownloadSock(ArqURL As String) 

    Dim arquivo() As Byte 
    Dim ficheiroID As Integer 

    ficheiroID = FreeFile 
    Me.Winsock1.Connect ArqURL, 80 

End Function 

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) 

    Dim ArqDestino As String 
    Dim arquivo() As Byte 
    Dim ficheiroID As Integer 

    ficheiroID = FreeFile 
    Open ArqDestino For Binary Access Write As #ficheiroID 
    Me.Winsock1.GetData arquivo() 
    Put #ficheiroID, , arquivo() 
    Close #ficheiroID 

End Sub 

這還遠遠沒有完成(然而也不是保證是語法正確的,認爲這是僞代碼)。進行連接之後,您必須實施一些機制來通知服務器開始發送文件。如果文件足夠大,則需要很多DataArrival事件才能完成所有操作,因此在數據遇到時必須將其保存在累加器中。這比你想象的還要多。

我會看看一些教程和/或示例代碼(找一個在CodeProject上使用Winsock控件的VB6項目,例如this one)。