2009-10-04 54 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)。