2009-10-04 9 views
3

J'essaie d'utiliser Winsock pour télécharger des fichiers et les enregistrer. Dans mon cas, j'ai un MSHFlexGrid avec 2 colonnes: une avec URL et l'autre avec le "chemin + nom de fichier" (où le fichier va être sauvegardé). J'itérer toutes les lignes d'appeler la fonction suivante:Winsock télécharger des fichiers - 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 

Je reçois cette erreur

40006: protocole incorrect ou connexion Etat pour la transaction demandée ou demande

Qu'est-ce que je fais mal?

Merci

Répondre

2

Avez-vous vérifié cette Microsoft Support page? Cela indique qu'il existe un bogue dans le contrôle Winsock et le correctif peut être utile.

Une autre chose à faire est de vous assurer que votre connexion Winsock est ouverte avant d'essayer de lire/envoyer des données, et si elle est fermée, ouvrez une nouvelle connexion:

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 

Vous pourriez aussi envisager de changer votre connexion code à quelque chose comme:

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

Une dernière chose. Découvrez this post sur l'utilisation du contrôle Winsock.

+1

Cette approche garderait tout asynchrone tout en évitant d'avoir à appeler 'DoEvents' en attente de' Winsock.State' pour changer. Je me méfie particulièrement de 'DoEvents' après avoir traité beaucoup trop de problèmes difficiles à déboguer causés par le code qui l'a utilisé, donc j'ai tendance à l'éviter à tout prix, même si cela semble être la façon facile de mettre en œuvre un boucle occupée-attente. –

1

Je pense que vous avez surestimé la puissance du contrôle Winsock. Vous ne pouvez pas simplement utiliser la méthode GetData de Winsock pour atteindre et récupérer un fichier. Il doit y avoir une connexion active entre votre application client et une autre application côté serveur. Une fois qu'une connexion est établie, cette application serveur alimentera votre application en données, l'événement DataArrival de Winsock se déclenchera, et vous pourrez ensuite utiliser la méthode GetData pour la récupérer. Votre code devrait ressembler à ceci:

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 

Ce qui est loin d'être complète mais (il n'est pas garanti d'être syntaxiquement correct, pensez à ce pseudo code). Une fois la connexion établie, vous devez implémenter un mécanisme pour indiquer au serveur de commencer à envoyer le fichier. Si le fichier est assez volumineux, il faudra beaucoup d'événements DataArrival pour tout obtenir, il devra donc être conservé dans un accumulateur pendant que les données sont partagées. Il y a plus à cela que vous ne le pensez.

Je voudrais jeter un oeil à quelques tutoriels et/ou exemple de code (recherchez un projet VB6 qui utilise le contrôle Winsock sur CodeProject, comme this one).

Questions connexes