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 :

plantage du serveur


Sujet :

Réseau C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 52
    Points : 29
    Points
    29
    Par défaut plantage du serveur
    Bonjour

    alors voila j'ai fini un projet mais il y a un problème.

    Il se compose d'une application client et serveur. Il y a quelque temps j'avais fait se projet pour Windows et récemment je l'ai adapté sur Linux (Client + serveur)

    je dispose d'un serveur sous Linux à domicile, par conséquent je vais mettre l'application serveur codé pour Linux sur le PC. Mais est-ce que un client dont les sockets sont exclusivement pour Windows pourra se connecter au serveur ? en théorie oui car il n'y a que les includes qui changent entre les 2 clients.

    autre chose. Il arrive à mon serveur (codé sur Linux) de s'arrêter celui de Windows ne coupait pas MAIS...
    je pense à une fuite de mémoire ou à une "surcharge".
    sous Windows comme sous Linux le serveur fonctionne correctement jusqu'à qu'il arrive un problème (pas très bon à mon avis) mais qui ne fait pas (sous Windows) s'arrêter le programme.

    Je vais essayer de vous expliquer en détaille se qui ce passe.

    -Le serveur attend une connexion
    -Client1 se connecte
    -Client1 écrit "il y a quelqu'un ?"
    -le serveur affiche "il y a quelqu'un ?" et le renvoi au(x) client(s)
    -Client2 se connecte
    -Client2 écrit "salut"
    -le serveur affiche "salut" et le renvoi au(x) client(s)
    -Client1 se déconnecte car il n'aime pas Client2
    -Le serveur par dans une boucle infini, la console deviens toute noir et la barre descend
    -Client2 écrit "il est nul Client1"
    -le serveur affiche et renvois le message (le serveur continu dans sa boucle infini mais on voit pendant 0.3 sec que le message s'affiche) par conséquent le problème vient de la fonction select ? (sous windows malgré se problème on peut continuer à se connecter, échanger des messages etc...)

    sous Linux le serveur crache soit:
    -Quand un client part (donc dès que la boucle infini se met en route)
    -quelque seconde après (de 5 sec à 1 min après le départ de la boucle)

    source du serveur sous Linux:
    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
     
    //serveur sous Linux
     
        #include <sys/types.h>
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <unistd.h>
        #define INVALID_SOCKET -1
        #define SOCKET_ERROR -1
        #define closesocket(s) close(s)
        #define PORT 23
        typedef int SOCKET;
        typedef struct sockaddr_in SOCKADDR_IN;
        typedef struct sockaddr SOCKADDR;
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #define CLIENT_MAX 1000
     
    struct vari
    {
    SOCKET s_server;
    SOCKET s_client;
    SOCKADDR_IN client;
    char buffer[1024];
    char buff[1024];
    int n;
    };
     
    void* maFonction(void* data);
     
    SOCKET s_global[CLIENT_MAX];
    int index_s = 0;
     
    int main(void)
    {
    int erreur = 0;
     
     
    SOCKET s_server;
     
            s_server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
     
            if (s_server == INVALID_SOCKET)
                fprintf(stderr, "La fonction socket a echoue.\n");
     
            else
            {
                SOCKADDR_IN server;
     
                server.sin_family       = AF_INET;
                server.sin_addr.s_addr  = htonl(INADDR_ANY);
                server.sin_port         = htons(PORT);
                memset(&server.sin_zero, '\0', sizeof(server.sin_zero));
     
                if (bind(s_server, (SOCKADDR *)&server, sizeof(server)) == SOCKET_ERROR)
                    fprintf(stderr, "La fonction bind a echoue.\n");
     
                else
                {
     
     
                    if (listen(s_server, 0) == SOCKET_ERROR) /* listen : commencer l'écoute */
                        fprintf(stderr, "La fonction listen a echoue.\n");
     
                    else
                    {
                        /* Création de l'ensemble de lecture */
                        fd_set readfs;
     
     
                        while (1)
                        {
                            /* On vide l'ensemble de lecture et on lui ajoute
                            la socket serveur */
                            FD_ZERO(&readfs);
                            FD_SET(s_server, &readfs);
     
                            /* On regarde si la socket serveur contient des
                            informations à  lire */
     
                            if(FD_ISSET(s_server, &readfs))
                            {
                                /* Ici comme c'est la socket du serveur cela signifie
                                forcement qu'un client veut se connecter au serveur.
                                Dans le cas d'une socket cliente c'est juste des
                                données qui serons reçes ici*/
     
                                SOCKET s_client;
                                SOCKADDR_IN client;
                                int csize = sizeof(client);
     
                                s_client = accept(s_server, (SOCKADDR *)&client, &csize);
     
                                /* La , on stocke l'identifiant reçu */
                                s_global[index_s++] = s_client;
     
                                if (s_client == INVALID_SOCKET)
                                    fprintf(stderr, "La fonction accept a echoue.\n");
     
                                else
                                {
     
                                    char buffer[1024];
                                    int n;
     
                                    printf("Le client %s s'est connecte !\n", inet_ntoa(client.sin_addr));
     
                                    strcpy(buffer, "Bonjour\n");
     
                                    send(s_client, buffer, (int)strlen(buffer), 0);
     
                                    n = recv(s_client, buffer, sizeof(buffer) - 1, 0);
     
                                    pthread_t thread;
                                    pthread_create(&thread, NULL, maFonction, &s_client);
     
                                }
     
                            }
                        }
                    }
     
                }
     
     
            }
     
     
        return 0;
    }
     
     
     
    void* maFonction(void* data)
    {
     
        struct vari res;
        res.s_client = *(int*)data;
     
        while (1) //boucle de réception et d'envois
        {
            memset(res.buffer, '\0', sizeof(res.buffer));
            res.n = recv(res.s_client, res.buffer, sizeof(res.buffer) - 1, 0); 
            printf("%s\n",res.buffer);    // j'affiche le message
            sprintf(res.buff, "%s", res.buffer);   // je copie le "buffer" dans "buff"
     
            /* Et la , on envoie à  tous les clients ! */
            int i;
            for (i = 0; i < index_s; i++)
            {
                send (s_global[i], res.buff, (int)strlen(res.buff), 0);  // envoie du buff
            }
        }
    }

  2. #2
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 21
    Points : 13
    Points
    13
    Par défaut
    C'est bizar, tu utilise un tableau avec un index global. Tu gère bien les connexions des clients mais tu gère pas les déconnexions.... Je ne suis pas sur que le problème vient de là mais à mon avis si il n'y a que ça dans ton serveur même sous windows si tu à plus de 1000 clients (ce qui parait peu probable) ou si tu as un seul clietn mal fait qui se déconnecte et se reconnecte plus de 1000 fois c'est normal que tu es un plantage.
    Sinon rajoute des gestions d'erreur sur les appels aux méthodes send et pthread create pour être sûr que le problème ne vient pas de là.
    Pour finir méfie toi un petit peu de tes variables globales que tu modifie dans ton thread principal et que tu utilises dans tes threads secondaire. Tu ne sais pas comment les threads seront ordonnancés (vu que tu ne le gère via les pthread_attr_t). Donc n'hésite pas à rajouter des lock pour être sur que tu n'essais pas d'accéder à une variable globale en cours de modification alors qu'il ne faudrait pas.
    Ensuite tu peux essayer de lancer ton serveur avec valgrind qui t'informera si il y a des erreurs mémoires qui peuvent expliquer ce plantage.
    en dernier recours si il n'y a pas d'erreurs détectées lors de l'exécution via valgrind (sous linux parce que sous windows je ne sais pas si ça existe!!) alors poste quand même le code du client pour que je puisse regarder de plus près le problème. A moins bien sur que l'erreur soit trop flagrante que je ne l'ai pas vu et que quelqu'un te l'ai fait remarquer.

    Bon voilà j'espère avoir pu t'aider un peu...

  3. #3
    Membre du Club Avatar de spin0us
    Profil pro
    Inscrit en
    Février 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 87
    Points : 64
    Points
    64
    Par défaut
    Euh closesocket c'est bien de le définir, mais faut penser à l'utiliser non
    Membre actif de la Pouy@geTe@m.

Discussions similaires

  1. Plantage du serveur non systématique
    Par floritude dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 19/02/2009, 12h22
  2. Semi-plantage et serveur trop bavard
    Par ludosoft dans le forum Apache
    Réponses: 3
    Dernier message: 18/02/2008, 18h15
  3. résolution graphique sans plantage du serveur X
    Par monsieur77 dans le forum Ubuntu
    Réponses: 5
    Dernier message: 25/11/2007, 18h14
  4. [KUBUNTU] Plantage du serveur X
    Par The_Pikos dans le forum Ubuntu
    Réponses: 5
    Dernier message: 15/02/2007, 21h10

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