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 :

Programme qui plante, pourquoi ?


Sujet :

Réseau C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2009
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2009
    Messages : 3
    Par défaut Programme qui plante, pourquoi ?
    Bonjour,

    Voila je programme un petit serveur HTTP (sous Windows) multi-thread (pthread) et ce dernier plante misérablement, ca fait un moment que je cherche d'où vient l'erreur mais je n'arrive pas a trouver.

    je poste le code complet :

    Header.h
    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
     
    ifndef HEADER_H_INCLUDED
    #define HEADER_H_INCLUDED
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <pthread.h>
    #include <sys/stat.h>
     
    struct cli
    {
       pthread_t thread;
       SOCKADDR_IN sin;
       int recsize;
       SOCKET sock;
    };
     
    void* Thread_Client(void* data);
    int pHTTP (void* data, char* Request);
    int Send_HTTP_Reply (void* data, int err);
    int Send_HTML_File(char *Path,void* data);
    int Send_File (void* data, char* Path);
     
    #endif // HEADER_H_INCLUDED
    main.c
    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
     
    #include "Header.h"
     
    int main()
    {
    WSADATA wsa_data;
     
    WSAStartup (MAKEWORD (2, 2), &wsa_data);
     
    SOCKET sock = socket (AF_INET, SOCK_STREAM, 0);
     
    SOCKADDR_IN sin = {0};
    sin.sin_addr.s_addr = htonl (INADDR_ANY);
    sin.sin_family = AF_INET;
    sin.sin_port = htons (80);
     
    bind (sock, (SOCKADDR *) &sin, sizeof sin);
     
    listen (sock, 5);
     
    struct cli *p_cli = NULL;
     
    do // Boucle
    {
     
    p_cli = malloc (sizeof *p_cli);
     
    if (p_cli != NULL)
    {
     
    p_cli->recsize = (int) sizeof p_cli->sin;
     
    p_cli->sock = accept (sock, (SOCKADDR *) &p_cli->sin, &p_cli->recsize);
     
    if (p_cli->sock != INVALID_SOCKET) // Client connecte ..
    {
     
          printf("Client connected with socket %d from %s:%d\n",
          p_cli->sock, inet_ntoa (p_cli->sin.sin_addr),
          htons (p_cli->sin.sin_port));
     
     
          pthread_create(&p_cli->thread,NULL,Thread_Client,p_cli);
          p_cli = NULL;
     
    }
    }
    else {
    puts("Error : memory allocation");
    }
     
    }while(1);
     
    WSACleanup ();
    return 0;
    }
    Thread.c
    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
     
    #include "Header.h"
     
    void* Thread_Client(void* data)
    {
    char Buff[512] = {0};
    fd_set  fdsr;
    struct timeval tv_timeout;
    int nb_bytes;
     
    struct cli *p_cli = data;
     
    if (p_cli == NULL)
    {
    puts("Error : Memory allocation");
    return NULL;
    }
     
    pthread_detach(p_cli->thread);
     
    FD_ZERO(&fdsr);
    FD_SET(p_cli->sock,&fdsr);
     
    tv_timeout.tv_sec = 2;
    tv_timeout.tv_usec = 0;
     
    // Timeout
    if (select(p_cli->sock+1,&fdsr,NULL,NULL,&tv_timeout) <= 0)
    {
        printf("Timeout %s:%d\n", inet_ntoa (p_cli->sin.sin_addr),htons (p_cli->sin.sin_port));
        goto end;
    }
     
    if (FD_ISSET(p_cli->sock, &fdsr)) // Si reception de données..
    {
        // Reception de la Requette HTTP du client
        nb_bytes = recv(p_cli->sock,Buff,sizeof(Buff),0);
        if(nb_bytes > 0) // Si supérieur a 0 Byte
        {
             // Gestion du protocole HTTP ..
             if(pHTTP(p_cli, Buff) != 0)
             {
                  puts("Intern Error");
             }
         }
         else {
         printf("Error recv \n");
         }
    }
     
    end:
     
    closesocket(p_cli->sock);
    p_cli->sock = INVALID_SOCKET;
    free(p_cli);
    p_cli = NULL;
    pthread_exit(0);
    return NULL;
    }
    HTTP.c
    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
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
     
    #include "Header.h"
     
    int Test_File(char* Path)
    {
    FILE * file = NULL;
    file = fopen(Path,"rb");
    if(file == NULL)
    {
        return 0;
    }
    fclose(file);
    return 1;
    }
     
    char* Format(char *Request, char *Path)
    {
    char *ptr = NULL;
    int i = 0;
     
    ptr = strstr(Request,"/");
    if(ptr != NULL)
    {
     
        ptr++;
        sprintf(Path,"%s",ptr);
        while (Path[i] != ' ')
        {
        i++;
        }
     
        Path[i] = 0;
        return Path;
     
    }
     
    return NULL;
    }
     
    int pHTTP (void* data, char* Request)
    {
    char Path[50] = {0};
    unsigned char *ptr;
    struct cli *p_cli = data;
     
    if (p_cli == NULL)
    {
    puts("Error : memory allocation");
    return 1; // Internal Server Error
    }
     
    // -- Test Version du protocol HTTP ---
    ptr = NULL;
    ptr = strstr(Request,"HTTP/1.1");
    if(ptr == NULL) // Si la version utilisé par le client n'est pas 1.1
    {
    puts("400 Bad Request");
    Send_HTTP_Reply(p_cli,400);
    Send_HTML_File("Bad_Request.html",p_cli);
    free(ptr);
    return 0;
    }
    //------------------------------------
     
    else // Si la version 1.1 est utilisée
    {
     
     //---------[GET METHOD]--------------------
        ptr = NULL;
        ptr = strstr(Request,"GET"); // Si methode GET du protocol HTTP
        if(ptr != NULL)
        {
     
              //------------[Demande page index.html]---------------------------
     
              ptr = NULL;
              ptr = strstr(Request,"/ HTTP/1.1"); // Si demande page index.html
              if(ptr != NULL)
              {
                    printf("%s:%d - HTTP GET METHOD - index.html\n",inet_ntoa (p_cli->sin.sin_addr),htons (p_cli->sin.sin_port));
                    if(Test_File("index.html") == 1) // Sil le fichier index.html est existant
                    {
                          Send_HTTP_Reply(p_cli,200);
                          if (Send_HTML_File("index.html",p_cli) == 1)
                          {
                              puts("Intern_Error");
                              Send_HTTP_Reply(p_cli,500);
                              Send_HTML_File("Intern_Error.html",p_cli);
                              free(ptr);
                              return 0;
                          }
                    }
                    else // Fichier introuvable ..
                    {
                        puts("404 NOT FOUND");
                        Send_HTTP_Reply(p_cli,404); //404
                        Send_HTML_File("Not_Found.html",p_cli);
                        free(ptr);
                        return 0; // Erreur interne car manque fichier principal html
                    }
              } // if index.html
     
     
              //-------------------[Demande fichier .jpg]-------------------------
              ptr = NULL;
              ptr = strstr (Request,".jpg"); // Si demande fichier .jpg
              if(ptr != NULL)
              {
                   ptr = NULL;
                   ptr = strstr(Request,"images/"); // Restriction
                   if (ptr != NULL)
                   {
                        // Format request ..
                        if (Format(Request,Path) != NULL)
                        {
                            if(Test_File(Path) == 1)
                            {
                                printf("%s:%d - HTTP GET METHOD - %s\n",inet_ntoa (p_cli->sin.sin_addr),htons (p_cli->sin.sin_port),Path);
                                if (Send_File(p_cli,Path) != 0)
                                {
                                    puts("error Send_File");
                                    Send_HTTP_Reply(p_cli,500);
                                    Send_HTML_File("Intern_Error.html",p_cli);
                                    free(ptr);
                                    return 1;
                                }
                                else
                                {
                                    printf("fichier envoye\n");
                                    free(ptr);
                                    return 0;
                                }
                            }
                            else
                            {
                                puts("404 NOT FOUND");
                                Send_HTTP_Reply(p_cli,404);
                                Send_HTML_File("Not_Found.html",p_cli);
                                free(ptr);
                                return 0;
                            }
                        }
                        else // Erreur intern, impossible de récupérer la Path
                        {
                              puts("Intern_Error 500");
                              Send_HTTP_Reply(p_cli,500);
                              Send_HTML_File("Intern_Error.html",p_cli);
                              free(ptr);
                              return 0;
                        }
     
                   }
                   else // Non respect de la restriction
                   {
                        puts("400 Bad Request");
                        Send_HTTP_Reply(p_cli,400); //400
                        Send_HTML_File("Bad_Request.html",p_cli);
                        free(ptr);
                        return 0; 
                   }
              } // if .jpg
     
     
        } // if get
     
    }
     
    return 0;
    }
    Reply.c
    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
     
    #include "Header.h"
     
    // Envoyer reponse HTTP au client
    int Send_HTTP_Reply (void* data, int err)
    {
    char Buff[70] = {0};
    struct cli *p_cli = data;
    if (p_cli == NULL)
    {
    puts("Error : memory allocation");
    return 1;
    }
     
    switch(err)
    {
    case 400: sprintf(Buff,"HTTP/1.1 400 BAD REQUEST\r\n"); break;
    case 404: sprintf(Buff,"HTTP/1.1 404 NOT FOUND\r\n"); break;
    case 500: sprintf(Buff,"HTTP/1.1 500 Internal Server Error\r\n"); break;
    case 200: sprintf(Buff,"HTTP/1.1 200 OK\r\n"); break;
    }
     
    send(p_cli->sock,Buff,strlen(Buff)+1,0);
    send(p_cli->sock,"Content-Type : text/HTML\r\n\r\n",strlen("Content-Type : text/HTML\r\n\r\n")+1,0);
     
    return 0;
    }
     
    // Envoi d'un fichier HTML
    int Send_HTML_File(char *Path,void* data)
    {
    struct stat stat_struct;
    char Page[500] = {0};
    struct cli *p_cli = data;
    if (p_cli == NULL)
    {
    puts("Error : memory allocation");
    return 1;
    }
     
    FILE *HTML = NULL;
    HTML = fopen(Path,"rb");
    if(HTML != NULL)
    {
    stat(Path,&stat_struct);
    while(fgets(Page,stat_struct.st_size,HTML) != NULL)
    {
    send(p_cli->sock,Page,strlen(Page)+1,0);
    memset(Page,0,sizeof(Page));
    }
    fclose(HTML);
    }
    else {
    return 1;
    }
     
    return 0;
    }
     
     
    int Send_File (void* data, char* Path)
    {
     
    FILE *file = NULL;
    int read = 0;
    char Buffer[512] = {0};
    struct cli *p_cli = data;
    if (p_cli == NULL)
    {
    puts("Error : memory allocation");
    return 1;
    }
    file = fopen(Path,"rb");
    if (file != NULL)
    {
     
         do{
     
              read = fread(Buffer,1,512,file);
              send(p_cli->sock,Buffer,read,0);
              memset(Buffer,0,sizeof(Buffer));
              if (read < 512)
              {
                  fclose(file);
                  break;
              }
     
         }while (1);
     
    }
    else {
    return 1; // Error
    }
     
    return 0;
    }
    Dans le répertoire de mon exe j'ai une page html toute simple
    nommée 'index.html', elle utilise une image de fond
    (<body background = "images/fond.jpg">).
    Le programme se crash si le client demande l'image, si je commente dans mon code html la balise body, le serveur ne plante pas..

    Si quelqu'un peut me dire ce qu'il se passe, merci d'avance.

  2. #2
    Membre Expert Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    Tu as pas mal de code, ce n'est pas évident de tout voir.

    Sais-tu à quel moment (ou mieux dans quelle fonction) ton serveur plante ?

    Pour t'aider, ajoute des traces.

  3. #3
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    On dirait que c'est le moment d'apprendre à utiliser un debugger

  4. #4
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Il faut compiler tes sources en mode debug (c'est une option de compilation), puis utiliser un debugger.

    Sur les IDE, c'est integre (cliquer sur "lancer en mode debug" au lieu de "lancer le programme"), et sinon, ca depend du compilateur et de l'OS.

    Exemple avec gcc sous Linux :
    passer l'option -g a gcc
    installer gdb, et aller lire de la documentation dessus.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2009
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2009
    Messages : 3
    Par défaut
    Bonsoir,

    gangsoleil
    Il faut compiler tes sources en mode debug (c'est une option de compilation), puis utiliser un debugger.
    J'utilise code:blocks, et mon 'Build target' est déjà en Debug.
    Quand je debug, gdb me retourne cela ->

    Building to ensure sources are up-to-date
    Build succeeded
    Selecting target:
    Debug
    Adding source dir: C:\Documents and Settings\M01\Bureau\Serv_Web\Serv_Web\
    Adding source dir: C:\Documents and Settings\M01\Bureau\Serv_Web\Serv_Web\
    Adding file: bin\Debug\Serv_Web.exe
    Starting debugger:
    done
    Registered new type: wxString
    Registered new type: STL String
    Registered new type: STL Vector
    Setting breakpoints
    Debugger name and version: GNU gdb 6.3
    Child process PID: 1648
    Program received signal SIGTRAP, Trace/breakpoint trap.
    In ntdll!DbgUiConnectToDbg () (ntdll.dll)

    fregolo52
    Sais-tu à quel moment (ou mieux dans quelle fonction) ton serveur plante ?
    Oui, je pense qu'il plante dans la boucle d’accueil des clients ou a la fin du thread. Le truc, c'est que si mon navigateur ne demande que la page index.html au serveur, celui ci ne plante pas..
    en revanche, si le navigateur fait la demande du .jpg le serveur plante.
    (Ma fonction Send_File n'est pas la source du problème, car si je la commente
    le crash persiste..)

    fregolo52
    Tu as pas mal de code, ce n'est pas évident de tout voir.
    dsl, mais j'ai déjà minimisé comme je pouvais le code, pour illustrer le problème.
    A la base mon projet est plus conséquent.

    merci.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2009
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2009
    Messages : 3
    Par défaut
    Problème résolu, mais je ne sais d'ou il venait ce problème ..
    J'ai fais une petite fonction pour formater la requête du client avant de la passer a la fonction pHTTP() .. et pouf, plus de bug.

    Bizarre quand même, il y a serrement une raison mais ca m'échappe..

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. programme qui plante
    Par warubi dans le forum C++
    Réponses: 35
    Dernier message: 04/02/2007, 10h57
  2. Programme qui plante : seg fault
    Par Premium dans le forum C
    Réponses: 10
    Dernier message: 01/12/2006, 15h12
  3. programme qui plante. chercher/remplacer dans des fichiers.
    Par [Hugo] dans le forum Général Python
    Réponses: 2
    Dernier message: 31/10/2006, 17h10
  4. Faire un programme qui plante et noter le plantage
    Par cedricgirard dans le forum Langage
    Réponses: 9
    Dernier message: 22/03/2006, 16h36
  5. Programme qui plante
    Par harris_macken dans le forum C++
    Réponses: 1
    Dernier message: 22/05/2005, 23h50

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