HTTP et ReceiveNetworkData

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
lepiaf31
Messages : 510
Inscription : dim. 25/mars/2007 13:44
Localisation : Toulouse, France
Contact :

HTTP et ReceiveNetworkData

Message par lepiaf31 »

Bonjour tout le monde !

J'ai un petit problème de reception de données. Voilà j'envoi une requete sur le port 80 et ensuite je voudrais récupèrer la reponse du serveur. Le problème c'est que je ne recoit pas la totalité des données ...

Code : Tout sélectionner

InitNetwork()

Host.s = "www.siteduzero.com"
Request.s = "GET /index.php HTTP/1.1"+#CRLF$+"Host: www.siteduzero.com"+#CRLF$+"Connection: Keep-Alive"+#CRLF$+#CRLF$
Conn = OpenNetworkConnection(Host, 80)
If Conn
  SendNetworkData(Conn, @Request, Len(Request))
  Delay(500)
  
  Result.s
  Repeat
    Buffer.s = Space(1024)
    Received = ReceiveNetworkData(Conn, @Buffer, 1024)
    Debug Received
    Result+Trim(Buffer)
  Until Received < 1024
  
  Debug Result
Else
  Debug "erreur"
EndIf
En effet, le serveur ne complete pas toujours le buffer du coup la boucle s'arrete et je n'ai pas la totalité du code source de la page :(
Quelqu'un a-t-il une solution pour savoir quand les données ont fini d'etre transmises ?
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

A mon avis, on ne devrait utiliser ReceiveNetworkData() qu'après un évenement #PB_NetworkEvent_Data en testant NetworkClientEvent(Connection).
Par exemple (non testé) :

Code : Tout sélectionner

  If NetworkClientEvent(Conn) = #PB_NetworkEvent_Data
    Buffer.s = Space(1024) 
    Received = ReceiveNetworkData(Conn, @Buffer, 1024) 
    Debug Received 
    Result+Trim(Buffer) 
  EndIf
Dernière modification par gnozal le lun. 31/août/2009 11:25, modifié 1 fois.
lepiaf31
Messages : 510
Inscription : dim. 25/mars/2007 13:44
Localisation : Toulouse, France
Contact :

Message par lepiaf31 »

Le probleme c'est qu'en faisant cela, je ne saurait pas quand j'aurais fini de receptionner toutes les données.

Code : Tout sélectionner

InitNetwork()

Host.s = "www.siteduzero.com"
Request.s = "GET /index.php HTTP/1.1"+#CRLF$+"Host: www.siteduzero.com"+#CRLF$+"Connection: Keep-Alive"+#CRLF$+#CRLF$
Conn = OpenNetworkConnection(Host, 80)
If Conn
  SendNetworkData(Conn, @Request, Len(Request))
  Delay(500)
  
  Result.s
  Repeat
    If NetworkClientEvent(Conn) = #PB_NetworkEvent_Data
      Buffer.s = Space(1024)
      Received = ReceiveNetworkData(Conn, @Buffer, 1024)
      Debug Received
      Result+Trim(Buffer)
    Else
      Delay(1)
    EndIf
  Until JeSaisPas ; <=== Probleme ici
  
  Debug Result
Else
  Debug "erreur"
EndIf
Parce qu'en fait, une fois la reponse recu en entiere, je voudrais la traiter.
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

Si tu ne connais pas la longueur des données à télécharger, tu peux ajouter un test sur le contenu.
Exemple, sur la balise </html> qui devrait signaler la fin du fichier HTML que tu télécharges :

Code : Tout sélectionner

InitNetwork() 

Host.s = "www.siteduzero.com" 
Request.s = "GET /index.php HTTP/1.1"+#CRLF$+"Host: www.siteduzero.com"+#CRLF$+"Connection: Keep-Alive"+#CRLF$+#CRLF$ 
Conn = OpenNetworkConnection(Host, 80) 
If Conn 
  SendNetworkData(Conn, @Request, Len(Request)) 
  Delay(500) 
  
  Result.s 
  Repeat 
    If NetworkClientEvent(Conn) = #PB_NetworkEvent_Data 
      Buffer.s = Space(1024) 
      Received = ReceiveNetworkData(Conn, @Buffer, 1024) 
      Debug Received 
      Result+Trim(Buffer) 
      If FindString(Buffer, "</html>", 1)
        Break
      EndIf
    Else 
      Delay(1) 
    EndIf 
  ForEver
  
  Debug Result 
Else 
  Debug "erreur" 
EndIf
lepiaf31
Messages : 510
Inscription : dim. 25/mars/2007 13:44
Localisation : Toulouse, France
Contact :

Message par lepiaf31 »

Ouais c'est vrai ... mais ça ne fonctionne pas pour tous les sites :( exemple: google, la dernière balise est </script>.
C'est bete quand meme il pourrait y avoir un evenement #pb_NetworkEvent_Disconnect coté client ca arrangerait pas mal de chose .

Quand on a la longueur ca va, mais quand on ne l'a pas ...
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

Si on utilise l'API Windows, on peut connaitre la longeur des fichiers à télécharger en utilisant

Code : Tout sélectionner

HttpQueryInfo_(hHttpOpenRequest,#HTTP_QUERY_RAW_HEADERS_CRLF,@Buffer$,@BufferLength,0) 
Voir http://www.purebasic.fr/english/viewtopic.php?p=217199
Avec les fonctions natives de PB, je ne sais pas. Je ne pense pas que GetHTTPHeader() revoie ces informations (?).
On peut toujours utiliser ReceiveHTTPFile(), mais les données sont écrites dans un fichier, pas en mémoire.
lepiaf31
Messages : 510
Inscription : dim. 25/mars/2007 13:44
Localisation : Toulouse, France
Contact :

Message par lepiaf31 »

gnozal a écrit : Je ne pense pas que GetHTTPHeader() revoie ces informations (?).
Hélas, le header ne contient pas toujours la taille du corps :(
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

Autre possibilité :

Code : Tout sélectionner

InitNetwork() 
Host.s = "www.siteduzero.com" 
Request.s = "GET /index.php HTTP/1.1"+#CRLF$+"Host: www.siteduzero.com"+#CRLF$+"Connection: Keep-Alive"+#CRLF$+#CRLF$
Conn = OpenNetworkConnection(Host, 80) 
If Conn 
  SendNetworkData(Conn, @Request, Len(Request)) 
  While NetworkEvent = 0
    NetworkEvent = NetworkClientEvent(Conn)
    Delay(1) 
  Wend
  If NetworkEvent = #PB_NetworkEvent_Data
    Repeat 
      Buffer.s = Space(1024) 
      Received = ReceiveNetworkData(Conn, @Buffer, 1024) 
      If Received <= 0
        Break
      EndIf
      Result.s + Left(Buffer, Received) 
      Debug Buffer
      Delay(1) 
    ForEver 
  EndIf
  Debug Result 
Else 
  Debug "erreur" 
EndIf
On attend NetworkClientEvent() puis on espère que les données arrivent ensuite en continu ...
lepiaf31
Messages : 510
Inscription : dim. 25/mars/2007 13:44
Localisation : Toulouse, France
Contact :

Message par lepiaf31 »

Oui j'avais déjà testé quelque chose dans ce genre mais les données n'arrivent pas toujours en continue ><. Enfin bon c'est vraiment casse-tete.
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

Autre possibilité :

Code : Tout sélectionner

#TimeOut = 5 ; Timeout de 5 s
InitNetwork() 
Host.s = "www.google.com" 
Arg.s = "search?hl=en&client=opera&rls=en&hs=0gm&q=purebasic&start=10&sa=N"
Request.s = "GET /" + Arg + " HTTP/1.1"+#CRLF$+"Host: " + Host +#CRLF$+"Connection: Keep-Alive"+#CRLF$+#CRLF$ 
Conn = OpenNetworkConnection(Host, 80) 
If Conn 
  SendNetworkData(Conn, @Request, Len(Request)) 
  Result.s 
  TimeOut = Date() + #TimeOut
  Repeat 
    If NetworkClientEvent(Conn) = #PB_NetworkEvent_Data 
      Buffer.s = Space(1024) 
      Received = ReceiveNetworkData(Conn, @Buffer, 1024) 
      Recu.s = Left(Buffer, Received)
      Result.s + Recu
      Debug Recu
      If Right(Recu, 4) = #CRLF$ + #CRLF$
        Break
      EndIf
      TimeOut = Date() + #TimeOut
    EndIf 
    If Date() > TimeOut
      Break
    EndIf
    Delay(10)
  ForEver 
EndIf
La réponse pour un site web semble toujours se terminer par #CRLF$ + #CRLF$ ; avec un timeout pour éviter une boucle infinie.
Répondre