Recuperer contenu requete http [Résolu]

Messages postés
198
Date d'inscription
lundi 24 avril 2006
Dernière intervention
3 avril 2008
- 28 juin 2007 à 14:38 - Dernière réponse :
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Dernière intervention
3 avril 2008
- 2 juil. 2007 à 21:06
Bonjour,
Je voudrais me connecter a mon serveur local afin de recuperer le contenu par exemple d'un fichier txt.
Grace a un code trouvé sur le site, j'arrive bien a créer ma socket avec Winsock, et a l'aide du GET, je rcupere bien des données. Cependant je ne récupère que l'entete de ma requete, or je voudrais moi ce qui se trouve en dessous, c'est a dire le contenu...
Voici la fonction que j'utilise :
void main(void)
 {
 WSADATA WSAData;
 WSAStartup(MAKEWORD(2,0), &WSAData);
 SOCKET sock;
 SOCKADDR_IN sin;

 char buffer[1024];
 char canal[50] = "GET /ecran.txt HTTP/1.0\nAccept: */*\n\n";

 sock = socket(AF_INET, SOCK_STREAM, 0);
 sin.sin_addr.s_addr = inet_addr("1.1.xx.xx"); // serveur local
 sin.sin_family = AF_INET;
 sin.sin_port = htons(80); // port HTTP.

 connect(sock, (SOCKADDR *)&sin, sizeof(sin)); // on se connecte
 send(sock, canal, strlen(canal), 0); // on envoie la requête HTTP.
 int i = recv(sock, buffer, sizeof(buffer), 0); // le buffer récupère les données reçues.
 if (i != 0) {
    EcrireFichierBidon(buffer); // j'ecris ce que je recupere dans un fichier
 }
 closesocket(sock); // on ferme le socket.
 WSACleanup();
 }

Voila, et je recupere ceci :
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 545
etc etc...

Si je regarde les flux transmit entre mon simulateur et le serveur, le stream de "/ecran.txt" me renvoi les memes données, suivi en dessous du contenu de mon fichier...

Merci!
Afficher la suite 

Votre réponse

13 réponses

Meilleure réponse
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Dernière intervention
17 septembre 2012
- 28 juin 2007 à 15:36
3
Merci
Salut,
Le content-length c'est la longueur des données qui suit la
réponse http du serveur, c'est donc la longueur du fichier qu'il te
renvois (545 octets dans ton cas).

Pour faire un truc propre, il faudrait:

1) faire des recv() en boucle jusqu'a avoir recu toute la réponse http,

2) extraire la valeur du champ Content-Length de la réponse http,

3) continuer a faire des recv() en boucle jusqu'a avoir recu tout le fichier.

Merci cs_aardman 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 89 internautes ce mois-ci

Commenter la réponse de cs_aardman
Meilleure réponse
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Dernière intervention
17 septembre 2012
- 28 juin 2007 à 18:31
3
Merci
Salut,

Mouais, je suis pas sur qu'un tableau a deux dimensions soit utile.

Deja une boucle simple, par exemple, pour remplir un buffer avec des recv en boucle ca aurait cette tête (à tester):

char buffer[1024];

int size 0, r 0;

while((r = recv(..., buffer + size, sizeof(buffer) - size, ...)) > 0)

{

    size += r;

    // ici tu traites les 'size' octets qui sont dans 'buffer'

}

Dans ta boucle tu verifie si tu as recu la requette http, et si oui tu
la parse et tu extrait Content-Length et tu sors de ta boucle.

Et la tu peux entrer dans une deuxieme boucle ou tu ecris tout ce que tu recois dans ton fichier (par exemple).
http://www.cppfrance.com/codes/TELECHARGER-FICHIER-WIN32-SOCKETS_24109.aspx

Merci cs_aardman 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 89 internautes ce mois-ci

Commenter la réponse de cs_aardman
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Dernière intervention
17 septembre 2012
- 28 juin 2007 à 15:15
0
Merci
Salut,

qu'est ce qui te dit que tu va recevoir toute la réponse et tout le fichier en un seul recv() ?

il faut faire des recv() en boucle jusqu'a avoir recu toute la reponse
plus la longueur des données specifiée dans le champ content-length de
la réponse.
Commenter la réponse de cs_aardman
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Dernière intervention
3 avril 2008
- 28 juin 2007 à 15:29
0
Merci
Je pensais (donc à tort ) que ca recupererai tant que le buffer ne serait pas plein...
Excuse moi aardman peux-tu développer un peu quand tu dis "plus la longueur des données specifiée dans le champ content-length de la réponse." Je n'ai pas trop compris. Moi concretement comme tu l'a vu, mon content length est de 545... C'est donc la longueur de tout le header present au dessus du contenu de mon fichier texte qui es de 545? Donc pourais commencer a recuperer a partir "d'apres" ce header?
Et la boucle je dois l'arreter en fonction de quoi?
En tout cas merci pour ta réponse rapide, je me repenche dessus
Commenter la réponse de fredsor
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Dernière intervention
3 avril 2008
- 28 juin 2007 à 15:44
0
Merci
Salut,
Ok pour tout récupérer, cependant je ne vois pas comment faire ma boucle de recv. Quels sont les parametres en plus que j'ai omis, pour dire par exemple que le deuxieme recv doit commencer où le 1er s'est arrété.
En gros j'ai testé en faisant deux recv consécutifs, et ils me renvoient deux fois l'entete de la requete...
Commenter la réponse de fredsor
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Dernière intervention
3 avril 2008
- 28 juin 2007 à 17:53
0
Merci
J'ai reussi a faire ma boucle, voici un aperçu :
 Avec un fichier contenant le texte  "coucou123"  ........
    char buffer[10][1024];
    int i=0;
    int j=0;
    while(i = recv(sock, buffer[j], sizeof(buffer[j]), 0))
    {
        if(i==9) // taille du content length ( je ferais la recuperation plus tard )
        {
            EcrireFichierBidon(buffer[j]);
        }
        j++;
    }
   
    clos
esocket(sock); // on ferme le socket.
.........
Je recuperer bien mon texte seulement.
Mais comme tu vois, ca me parait etre une methode asez bourrine... Donc j'aimerais savoir ce que tu en pense. SI tu crois que ca peut passer et que de toute maniere je ne pourrais pas faire autrement, n'hésite pas
Donc a priori il me reste a recuprer le content length, et de rechercher lorsque "i" est égal a cette quantité...?
Commenter la réponse de fredsor
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Dernière intervention
3 avril 2008
- 29 juin 2007 à 09:32
0
Merci
Impec aardman, je devrais m'en sortir avec ca (ca foncitonne, me reste que le travaille de parsing)

Je profite de ta bonté ^^, j'ai une derniere petite question... Apres récupération du fichier et traitement associé, je dois etre capable de renvoyer une chaine de caractère à travers une autre url.
Dois-je faire un 'send' de la meme maniere? Je suppose que pour créer une nouvelle requete valide, je devrais insérer un en-tete semblable à celui récupéré précédemment? Donc devrais-je créer un send pour l'entete, puis un autre avec ma chaine de caractere?
Ou y-a-t-il de nouvelles notions que je devrais m'empresser de voir?

Je te remercie pour ton attention!!
Commenter la réponse de fredsor
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Dernière intervention
17 septembre 2012
- 29 juin 2007 à 18:25
0
Merci
Salut,

Si tu veux envoyer une chaine au serveur http, c'est plutot une requette POST qu'il faudrait faire.

Mais sinon ca reste le même systeme, une requette suivie des données,
la longueur des données est toujours dans Content-Length. Le mieux
serait de regarder dans la rfc http pour etre sûr.
Commenter la réponse de cs_aardman
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Dernière intervention
3 avril 2008
- 30 juin 2007 à 11:54
0
Merci
Merci aardman, je vais regardé du coté de la rfc
Par contre sais tu coment fonctionnent les requetes POST avec winsock?
Aurait tu un exemple?
Car sinon jai bien envoyer une chaine "hello world" avec send, et avec Wireshark je situe bien un paquet contenant cette chaine, mais apres je sais pâs si cette reqeute est valable...
Donc voila, sit u sais comment géré les requete POSt, je suis tout ouïe
Merci!
Commenter la réponse de fredsor
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Dernière intervention
17 septembre 2012
- 1 juil. 2007 à 19:27
0
Merci
Salut,

Une requete post a exactement le meme format qu'une requette get, mais
peut etre qu'il faut obligatoirement specifier certains champs (si tu
envoies des données, je pense que Content-Length est obligatoire par
exemple).
Commenter la réponse de cs_aardman
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Dernière intervention
3 avril 2008
- 2 juil. 2007 à 09:02
0
Merci
Salut,
Ok pour le content length, mais en fait c'est que je ne vois pas "comment " l'envoyer...
Je dois tout écrire "à la main"? genre Content-Length : sizeof(...) etc
De plus, si je veux faire quelque chose du genre
    char canal[50] = "POST / HTTP/1.0\nAccept: */*\n\n";
    ...
    send(sock, canal, strlen(canal), 0);
Il n'en veux pas, pretextant n'accepter qu'un "Get " ou un "Head"...

Donc sais-tu à quel moment vais-je spécifier que c'est une requete POST? et vois-tu comment envoyer l'en-tete ( ou alors connais tu comment  n'envoyer que ses données et son content-length, et que le tout se forme automatiquement...)
Désolé je suis un peu perdu, ca me fait peur tout ça ...
Commenter la réponse de fredsor
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Dernière intervention
17 septembre 2012
- 2 juil. 2007 à 18:00
0
Merci
Salut,

Biensur que tu dois tout écrire a la main, rien n'est automatique... il
faut donc formatter toi meme ta requette, avec sprintf par exemple.

Pour le POST je ne prefere pas m'avancer, comme je te l'ai dis je maitrise pas trop donc je te laisse chercher dans la doc.
Commenter la réponse de cs_aardman
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Dernière intervention
3 avril 2008
- 2 juil. 2007 à 21:06
0
Merci
Merci bien aardman, j'ai fais quelque recherche et en effet on doit formatter sa requete... Apres je ne sais pas encore si elle est valable car lorsque je veux la recuperer ensuite, ca veut pas il la trouve pas
Merci pour l'attention, je continue mes recherches
A pluche
Commenter la réponse de fredsor

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.