IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Problème protocole HTTP


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mars 2017
    Messages : 8
    Par défaut Problème protocole HTTP
    Bonjour,

    Je n'avais jamais utilé C pour traiter des requêtes HTTP, mais là je dois m'y mettre.

    Donc j'ai programmé, en me renseignant, un petit code destiné à transmettre progressivement un fichier audio. Le destinataire est une balise audio avec src="www.....:8003".

    Le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(param) close(param)
    #define PORT 8003
     
     
     
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
     
     
    void main(){
     
    system("fuser -k 8003/tcp");
    usleep(100000);
     
    struct sockaddr_in
    {
        short      sin_family;
        unsigned short   sin_port;
        struct   in_addr   sin_addr;
        char   sin_zero[8];
    };
     
    SOCKET sock;
    SOCKADDR_IN sin;
    SOCKET csock;
    SOCKADDR_IN csin;
     
    socklen_t recsize = sizeof(csin);
    int sock_err;
     
    char buffer[5000];
     
    sock = socket(AF_INET, SOCK_STREAM, 0);
     
     
            if(sock != INVALID_SOCKET)
            {
                printf("Le socket %d est maintenant ouvert en mode TCP/IP\n", sock);fflush(stdout);
     
                /* Configuration */
                sin.sin_addr.s_addr    = htonl(INADDR_ANY);   
                sin.sin_family         = AF_INET;  
                sin.sin_port           = htons(PORT);
                sock_err = bind(sock, (SOCKADDR*)&sin, sizeof(sin));
     
     
                if(sock_err == SOCKET_ERROR){printf("erreur socket");}
                if(sock_err != SOCKET_ERROR)
                {
     
                    sock_err = listen(sock, 5);
                    printf("Listage du port %d...\n", PORT);fflush(stdout);
     
     
                    if(sock_err != SOCKET_ERROR)
                    {
     
                        printf("Attente de connexion sur le port %d...\n", PORT);fflush(stdout);
     
                        csock = accept(sock, (SOCKADDR*)&csin, &recsize);
                        printf("Un client se connecte avec le socket %d de %s:%d\n", csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));
     			fflush(stdout);
     
                        recv(csock,buffer,sizeof(buffer),0);
     
                        printf("Réponse du client : %s\n",buffer);fflush(stdout);
     
     		char buff[1000]="";
     		char buff2[45];
     		char tmp[10];
     		char buff3[1280] ;
                    char ent[4000];
     
     
    		FILE* entete=fopen("entete","r");
    		int l=fread(buff2,44,1,entete);
    		fclose(entete);
     
     
                    sprintf(ent,"HTTP/1.1 206 Partial Content\r\n"
                    "Content-Transfer-Encoding: bytes\r\n"
                    "Content-Type: audio/wav\r\n"
                    "Content-Length:44\r\n"
                    "Content-Range: bytes 0-43/96000044\r\n\r\n%s",buff2);
                    send(csock,ent,strlen(ent), 0); 
                    printf("emission\n%s\n\n",ent);fflush(stdout);
     
     
                    recv(csock,buffer,5000,MSG_DONTWAIT);
     		usleep(100000);                    
                    printf("Réponse du client : %s\n\n",buffer);fflush(stdout);
     
     
     
     
                    long pos=44;
                    FILE * in=fopen("dat.wav","r");
                    while(1)
                    {
                    //emission
                    int l=fread(buff3,2,640,in);
                    sprintf(ent,"HTTP/1.1 206 Partial Content\r\n"
                    "Content-Transfer-Encoding: bytes\r\n"
                    "Content-Type: audio/wav\r\n"
                    "Content-Length:%d\r\n"
                    "Content-Range: bytes %ld-%ld/96000044\r\n\r\n%s"
                    ,2*l,pos,pos+2*l-1,buff3);
                    pos+=(2*l);
                    int i=strlen(ent);
     
                    send(csock,ent,2*l+i, 0); 
     
                    printf("emission\n%s\n\n",ent);fflush(stdout);
     
                   // reception
                    recv(csock,buffer,5000,MSG_DONTWAIT);
                    printf("\n\nRéponse du client : %s\n",buffer);fflush(stdout);
     
                    usleep(1000);  
                    }      
                        shutdown(csock, 2);
                    }
                }
     
     
                closesocket(sock);
            }
    }
    Je lance le truc, et m'y connecte.

    D'abord, les recv sont bloquant à partir du deuxième, et j'ai mis des "MSG_DONTWAIT" et une temporisation.

    Ensuite, le récepteur semble ignorer mes envois, et requiert toujours la même chose :

    Un log du début:

    Un client se connecte avec le socket 4 de 86.244.233.115:61265
    Réponse du client :

    GET / HTTP/1.1
    Host: www.xxx.fr:8003
    Connection: keep-alive
    Accept-Encoding: identity;q=1, *;q=0
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 OPR/67.0.3575.137
    Accept: */*
    Referer: http://www.xxx.fr/cours/socket/ecouter.php
    Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
    Range: bytes=0-


    emission
    HTTP/1.1 206 Partial Content
    Content-Transfer-Encoding: bytes
    Content-Type: audio/wav
    Content-Length:44
    Content-Range: bytes 0-43/96000044

    RIFF$ظWAVEfmt 

    Réponse du client : GET / HTTP/1.1
    Host: www.xxx.fr:8003
    Connection: keep-alive
    Accept-Encoding: identity;q=1, *;q=0
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 OPR/67.0.3575.137
    Accept: */*
    Referer: http://www.xxx.fr/cours/socket/ecouter.php
    Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
    Range: bytes=0-



    emission
    HTTP/1.1 206 Partial Content
    Content-Transfer-Encoding: bytes
    Content-Type: audio/wav
    Content-Length:1280
    Content-Range: bytes 44-1323/96000044

    etc...



    Réponse du client : GET / HTTP/1.1
    Host: www.xxx.fr:8003
    Connection: keep-alive
    Accept-Encoding: identity;q=1, *;q=0
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 OPR/67.0.3575.137
    Accept: */*
    Referer: http://www.xxx.fr/cours/socket/ecouter.php
    Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
    Range: bytes=0-


    Bref, le client me demande toujours "Range: bytes=0-", et ignore visiblement les envois.

    Je suppose que j'ai des problèmes d'entêtes HTTP. et pourquoi les "recv", à partir du deuxième, sont bloquants?

    Quelqu'un connaît-t-il bien ceci?

    Merci d'avance

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    - Si le problème est que le client envoie de mauvaises données alors le souci est dans le code du client
    - recv est toujours bloquant si le socket est bloquant
    - recv ne reçoit pas X octets mais jusque X
    - le protocole http est très complexe et il vaut mieux utiliser une lib pour l'utiliser

    https://bousk.developpez.com/cours/r...voi-reception/
    https://bousk.developpez.com/cours/r...ption-serveur/
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre régulier
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mars 2017
    Messages : 8
    Par défaut
    Bonsoir, et merci de votre réponse.

    Pour ce qui est des liens, je les ai déjà parcouru (C++, pas C, mais bon). Ceci-dit le problème n'est pas là je pense, mais dans le protocole.

    Quelles librairies en C (pas C++)?

    Ceci-dit, j'aimerais bien m'en passer. Normalement, le protocole HTTP est clair, et pas spécialement compliqué.

    Boucle envoi/réponse, header et contenu. Tout est bien renseigné.

    Pour l'envoi d'une page simple, sans contenu partiel, j'y arrive sans souci.

    C'est vraiment la gestion de l'envoi progressif qui pose problème.

    Habituellement, je fais ça en PHP, et n'utilise C que pour les routines calculatoires qui doivent être rapides, comme du multiplexage de sons.

    Mais dans mon problème actuel, PHP consomme trop de ressources.

    Je vais continuer à investiguer, et remercie d'avance pour toute réponse.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Le protocole http est couvert par plusieurs rfc qui dépassent la cinquantaine voire centaine de pages chacune.
    Oui tu peux créer un truc rapide et bancal qui renvoit un résultat, mais il couvrira pas tous les cas, ou tous les navigateurs.
    Quand on sait à peine gérer un socket, considérer ça complexe me parait pas abusif.
    Le streaming semble couvert par la rfc 8216 https://tools.ietf.org/html/rfc8216.
    Oui mes exemples sont en C++, mais l'api est en C. Passer de l'un à l'autre est assez trivial, et surtout le code C++ est totalement décorrélé des explications de l'API socket qui sont valides quel que soit le langage utilisé par dessus.
    Parmi les plus connus il y a libcurl, qui revient constamment sur ce forum. Google en sort rapidement d'autres comme libhttp par exemple https://github.com/lammertb/libhttp.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre régulier
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mars 2017
    Messages : 8
    Par défaut
    Bon, je vais regarder libcurl.

    Ceci-dit, j'aime bien comprendre les choses, et vais continuer à chercher. Peut-être du "retro-engineering" en me connectant via un client programmé en C à un script php qui fait l'équivalent pour analyser le processus de négociation HTTP.
    Je ne suis pas un pro des sockets, vu que je commence juste à les utiliser, mais pas une crêpe en C quand même. J'utilise des threads, des communications inter-processus via des pipes, etc... Mais C n'est pas mon langage principal, je ne m'en sers que pour ce qui est trop long à traiter via des langages plus haut niveau.


    Merci.

  6. #6
    Membre régulier
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mars 2017
    Messages : 8
    Par défaut
    A ben non, libcurl est un client HTTP. Ce qu'il me faut est un serveur.
    J'ai vu passer "libonion". Vais essayer...

Discussions similaires

  1. Crypt::SSLeay : Problème d'installation du protocole HTTPS
    Par cpt_aimless dans le forum Modules
    Réponses: 1
    Dernier message: 15/07/2009, 13h51
  2. [PhpMyVisites] problème sur la prise en charge du protocole https
    Par gorgonite dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 29/01/2007, 08h09
  3. Protocole HTTP: methode POST
    Par Nyx dans le forum Général Conception Web
    Réponses: 15
    Dernier message: 01/04/2005, 17h45
  4. identification sur le protocole HTTP
    Par windob dans le forum Développement
    Réponses: 20
    Dernier message: 31/03/2004, 22h52
  5. Problème lié au protocole HTTP.
    Par giviz dans le forum Développement
    Réponses: 2
    Dernier message: 03/10/2003, 17h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo