Page 1 sur 1
HTTP et ReceiveNetworkData
Publié : lun. 31/août/2009 11:04
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 ?
Publié : lun. 31/août/2009 11:18
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
Publié : lun. 31/août/2009 11:23
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.
Publié : lun. 31/août/2009 11:36
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
Publié : lun. 31/août/2009 11:44
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 ...
Publié : lun. 31/août/2009 11:52
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.
Publié : lun. 31/août/2009 11:58
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

Publié : lun. 31/août/2009 12:44
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 ...
Publié : lun. 31/août/2009 13:36
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.
Publié : lun. 31/août/2009 14:57
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.