Winsock dans une boucle ???

Résolu
Signaler
Messages postés
138
Date d'inscription
vendredi 1 août 2003
Statut
Membre
Dernière intervention
16 juillet 2009
-
Messages postés
138
Date d'inscription
vendredi 1 août 2003
Statut
Membre
Dernière intervention
16 juillet 2009
-
Salut, bon j'ai un post en cours sur Inet, mais comme ce controle n'a
pas l'air de fonctionner pour tous les sites, je suis obligé d'utiliser
winsock. (webbrowser reformate la source des pages, je dois garder le
format original, je ne peux donc pas l'utiliser)



Bref je dois me servir de winsock.

Tout marche tres tres bien, je récupère la source des pages que je veux, impeccable.



Mais ça se complique quand dans le même code j'essaye de récupérer deux sources de deux pages différentes.



J'ai testé plusieurs méthodes :



For i = 1 to n

URL( i )

Winsock1.Close

Winsock1.RemoteHost = "monsite.com"

Winsock1.RemotePort = 80

Winsock1.Connect

Next i



J'explique un peu le code ci dessus : la variable URL dépend de i,
c'est une string. Elle est appelée dans le Winsock_connect( ). Les
syntaxes sont OK (j'ai testé séparément, je récupère bien les sources)

Avec ca rien ne fonctionne.

Et si j'enleve le winsock1.close, il me répond qu'on ne peut pas se connecter a cet état.

Donc cette méthode est pourrie, j'ai alors testé autre chose.



Private Sub Ma_sub()

Winsock1.Close
Winsock1.RemoteHost = "monsite.com"
Winsock1.RemotePort = 80
Winsock1.Connect

End Sub



Private Sub Winsock1_connect()

Dim CommandeHTTP As String

Dim URLPageWeb As String



For i = 1 To 14



go = False



CommandeHTTP = ""

CommandeHTTP = "GET " & URL( i ) & " HTTP/1.0" & vbCrLf & _

"Accept: */*" & vbCrLf & _

"Accept: text/html" & vbCrLf & vbCrLf



Winsock1.SendData CommandeHTTP



While go = False

DoEvents

Wend



Next i

End Sub



Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)

On Error Resume Next

Dim HTTPDonnees As String



Winsock1.GetData HTTPDonnees, vbString



src = src + HTTPDonnees



If instr(src,"</html>") Then

recup_valeurs (src)

go = true

End If



End Sub



Explications :



Dans ma_sub( ) j'appelle le winsock, dans connect, j'ai ma boucle, c'est assez clair, a part peut etre l'histoire du go.

C'est une public boolean, qui permet d'attendre que l'on ait récupéré
la fin de la page (la balise </html>) pour passer a la suivante.



Ca ne marche evidemment pas, ce serait trop simple bien sur

La premiere passe de la boucle fonctionne, mais pour i=2 j'ai le message d'erreur suivant :

Run-time error '40006':

Wrong protocol or connection state for the requested transaction or request

Et le focus est sur Winsock1.SendData CommandeHTTP



J'ai essayé de mettre des winsock1.close un peu a tous les endroits,
j'ai essayé de récupérer les winsock1.state a un peu tous les endroits
de mon code et de bidouiller avec des connect, mais rien a faire.



Ma question est donc la suivante, est-il possible d'envoyer deux fois de suite un senddata ? et comment ?



Je pense qu'il doit exister un truc pour garder ouvert la connexion, ou
un truc du genre, mais j'ai beau fouiller je ne trouve pas.



Un grand merci a ceux qui aurons pris la peine de me lire jusqu'au
bout, et un merci encore plus grand a ceux qui me repondrons :)



Bonne soirée.



Guizmo

11 réponses

Messages postés
571
Date d'inscription
vendredi 30 décembre 2005
Statut
Membre
Dernière intervention
12 juillet 2012
3
Salut ça commence à prendre forme, ton affaire.



Effaces la boucle de DoEvents qui ne sert strictement à rien.



404 bad request tu dis? On voit qu' il manque un espace dans la
requête. Mais ou? ihihihi là où il faut enlever un vbcrlf. Regardes la
section 5.1.2 de la RFC 2616. Elle donne cet exemple:

GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.w3.org




Aussi j'anticipe un peu, il faut un string pour chaque socket, pour que
chaque paquet arrivant soit concaténé au string associé au socket. Un
tableau de strings dont l' index sera corrélé à ceux du tableau URL et
celui des sockets fera l' affaire. Ca donne



Private Sub Winsock1_DataArrival(index As Integer, ByVal bytesTotal As Long)

Dim HTTPDonnees As String

Winsock1(index).GetData HTTPDonnees, vbString

src(index) = src(index) & HTTPDonnees

recup_valeurs src(index), index

End Sub
3
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 109 internautes nous ont dit merci ce mois-ci

Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
81
Salut
Donc, c'est un aspirateur de site (à ne pas essayer sur vbfrance sous peine de bannissement automatique de l'IP)
Quand ton programme plante sur ton erreur, quel est l'état du Winsock ?
S'il est en erreur, c'est que le lien n'est pas correct.
S'il est fermé, il faut l'ouvrir.
Mais il faut approfondir les méthodes d'échanges GET (qui je crois a un paramètre KeepAlive) et attendre le résulat et l'analyser éventuellement.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage. (Socrate)
Messages postés
3140
Date d'inscription
vendredi 14 mai 2004
Statut
Membre
Dernière intervention
11 mars 2019
31
avec le protocole HTTP/1.1 la connection est continue par défaut, tant qu'il n'y a pas une "connection: close" dans la demande.

encore faut il que celle ci soit acceptée donc vérifier la réponse:

HTTP/1.1 100 Continue



NB: un seul Accept suffit
"Accept: text/html, */*"
Daniel
Messages postés
138
Date d'inscription
vendredi 1 août 2003
Statut
Membre
Dernière intervention
16 juillet 2009

Merci pour vos réponses.



Il ne faut pas se fier aux apparences, j'essaye toujours de faire des
posts avec des codes neutres, qui ne laissent rien transparaitre du
programme que je veux faire (mis a part le code lui meme, je parle des
noms ect ect .. ) et ceci dans le seul soucis de lisibilité de mon code.



Il va servir a rapatrier des données venant d'un site, certes, mais
c'est un site recensant les joueurs d'un jeu, et c'est dans le but de
faire un jeu de statistiques complet sur les membres de la guidle de
joueur dont je suis le chef que je veux rapartier ces données ... ce
n'est pas vraiment ce que j'appelle un aspirateur de site.



Ceci étant dit, j'ai testé la methode du HTTP/1.1, visiblement le site n'accepte pas la connection, donc c'est raté.



Lorsque le programme plante, l'état du winsock est a 8, la connection
est donc fermée, c'est pour cela que je n'arrive pas refaire senddata.



J'ai essayé de placer un connect, mais je ne trouve pas d'endroits corrects dans mon code tel qu'il est.

En ce qui concerne un eventuel attribut keepalive, j'ai beau retourner
MSDN (le site) dans tous les sens, je n'arrive pas a lui faire cracher
les attributs de GET.

J'ai googleïfié le probleme, meme résultat.



Je vais encore chercher.



@+ (je ne pourrais pas trop répondre dans la semaine, ne vous inquietez pas, je ne n'aurais pas cramé le PC :) )

ZeGuizmo
Messages postés
3140
Date d'inscription
vendredi 14 mai 2004
Statut
Membre
Dernière intervention
11 mars 2019
31
l'état du Winsock à 8 n'est pas encore fermé,

il est seulement en cours de fermeture ...

avant d'envoyer un nouveau connect, il doit être à zéro





sinon essaye ça:

"connection: Keep-Alive"
si acceptée, on retrouve la même chose dans le header de la réponse.


Daniel
Messages postés
138
Date d'inscription
vendredi 1 août 2003
Statut
Membre
Dernière intervention
16 juillet 2009

J'avais cherché partout sauf sur vbfrance ;) j'ai trouvé un exemple de keep-alive, je l'ai testé vite fait, pour i = 4 ca bug :(

Je n'ai plus le temps, mais je vais me pencher sur le probleme le week end prochain.



CU le week end prochain, je vous dirais si j'ai reussi.



++

ZeGuizmo
Messages postés
571
Date d'inscription
vendredi 30 décembre 2005
Statut
Membre
Dernière intervention
12 juillet 2012
3
Salut les amis :)




Inet fonctionne pas sur tous les sites?!? Tu m' étonnes là.



Vu ton code actuel, envoyer 14 requêtes au serveur en moins de 0.1
milliseconde revient à n' envoyer que la dernière et fatiguer le
serveur. Pas bueno. Au mieux tu te retrouves avec un gros paquet de
données enchevetrées dans le même sac et impossible à trier.



Sans hésitation, il faut un socket par connection. Chacun va ouvrir un
port dynamique en local ça garantira la fiabilité sur réception des
données.



Mets un socket indexé sur ta feuille, et charges les autres
dynamiquement avec load(). En plus l' index du socket sera également l'
index de ton tableau URL(). Nickel non? Et sur évènement Sendcomplete()
un unload sock(i) pour libérer les ressources.
Messages postés
138
Date d'inscription
vendredi 1 août 2003
Statut
Membre
Dernière intervention
16 juillet 2009

Salut katsanka,



J'ai réussi a squater une connection internet pour quelques minutes et je suis donc venu voir les réponses.



Je ne comprend pas tres bien ta remarque. Je suis loin d'être un expert
en VB, je ne sais meme pratiquement rien faire avec, donc ca touche
certainement des domaines que je ne connais pas, mais peut etre as-tu
mal lu le code.



En effet, avec la boolean go, j'attend systématiquement d'avoir chopé
le </html> (donc la fin de la page en cours) pour envoyer la
requete suivante. Donc je pense que le probleme que tu souleves est
écarté.



Mais comme je le dis, je ne suis pas un expert, et parfois les controles ne réagissent pas comme on se l'imagine.



En ce qui concerne le controle inet, va voir ce post (de moi egalement) qui expose mon probleme.

http://www.vbfrance.com/forum.v2.aspx?ID=650813



Pour les 14 requetes, c'était pour l'exemple. Le code final executera
la boucle 400 fois pour balayer tous les profils des membres actifs de
la guilde (qui sont au nombre de 200 en permanence).

Je ne suis pas idiot, et le code final sera executé a une heure plus
que tardive de la nuit, pour ne pas causer de dérangements sur le site.



Je teste toutes ces modifs ce week end et je vous tiendrais au courant.



@+ et merci encore


ZeGuizmo
Messages postés
138
Date d'inscription
vendredi 1 août 2003
Statut
Membre
Dernière intervention
16 juillet 2009

Salut salut,



Bon mon code etait tout pourri, rien ne marchait, je me suis donc renseigné sur les index de winsock.



Apres avoir bouffé quelques codes-exemple j'ai pondu ca, mais ca ne fonctionne pas :



Dans mon bouton qui lance le tout j'ai mis



For i = 1 To 20

go = False

Load Winsock1(i)

Winsock1(i).RemoteHost = "monsite.com"

Winsock1(i).RemotePort = 80

Winsock1(i).Connect

DoEvents

While go = False

DoEvents

Wend

Next i



Private Sub Winsock1_connect (index As Integer)

Dim CommandeHTTP As String

CommandeHTTP = "GET " & URL(index) & vbCrLf
& "HTTP/1.0" & vbCrLf & "Accept: */* , text/html" &
vbCrLf & vbCrLf

Winsock1(index).SendData CommandeHTTP

DoEvents

End Sub



Private Sub Winsock1_DataArrival(index As Integer, ByVal bytesTotal As Long)

On Error Resume Next

Dim HTTPDonnees As String



Winsock1(index).GetData HTTPDonnees, vbString



src = src + HTTPDonnees



While instr(src,"<html/>")

DoEvents

Wend



go = True



DoEvents



recup_valeurs src, index



End Sub



Et je ferme mes connections dans ma fonction recup valeur, je unload
mon controle dans le winsock1_close, j'ai laissé mon boolean go pour ne
pas aller trop vite dans la recupération des pages



Le soucis, c'est que le controle winsock qui fonctionnait tres tres
bien avant, ne fonctionne soudainement plus, avec exactement le meme "
GET [...] "

Il me sort systématiquement erreur 404; et un texte bidon en me disant bad request machin truc.



Le controle winsock avec un index ne fonctionnerait plus comme le controle winsock sans index ??? Ou j'ai pas pigé un truc ?



Merci encore :) (oui je suis chiant avec mon winsock)


ZeGuizmo
Messages postés
571
Date d'inscription
vendredi 30 décembre 2005
Statut
Membre
Dernière intervention
12 juillet 2012
3
Gobillot t'avais indiqué d'utiliser HTTP/1.1 si tu lis pas les réponses ça risque d'être plus long.
Messages postés
138
Date d'inscription
vendredi 1 août 2003
Statut
Membre
Dernière intervention
16 juillet 2009

Yeaaapee ca fonctionne en enlevant le vbcrlf :)



Merci beaucoup a vous tous.



Et au fait, celui des deux qui ne lit pas les réponses ... ce n'est pas moi



Juste en dessous du message de Gobillot



" Ceci étant dit, j'ai testé la methode du HTTP/1.1, visiblement le site n'accepte pas la connection, donc c'est raté."



Merci encore, et bonne prog !


ZeGuizmo