Plantage du serveur

cs_Adict Messages postés 28 Date d'inscription vendredi 1 janvier 2010 Statut Membre Dernière intervention 10 août 2010 - 10 août 2010 à 18:53
fregolo52 Messages postés 1114 Date d'inscription mercredi 15 juin 2011 Statut Membre Dernière intervention 6 mai 2021 - 11 août 2010 à 08:26
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:
//serveur sous Linux

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include 
    #include 
    #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 
#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
        }
    }
}

1 réponse

fregolo52 Messages postés 1114 Date d'inscription mercredi 15 juin 2011 Statut Membre Dernière intervention 6 mai 2021 4
11 août 2010 à 08:26
salut,

pour moi ton code ne correspond pas à ton scénario.
Pourquoi tu as cette ligne dans le thread principal ? :
n = recv(s_client, buffer, sizeof(buffer) - 1, 0);


Ton code ne gère pas les déconnexions.
    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); 
        if (res.n < 0)
            break;
        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
        }
    }
0
Rejoignez-nous