Journal Aide en C

Posté par  .
Étiquettes : aucune
0
21
mar.
2004
Cher journal, j'ai entrepris ce matin la création d'un petit chat en C, histoire de tester les sockets sous unix (je ne connais que le socket sous windows, et pas en C...)

Bref, le code me parait assez clair, mais je m'embrouille un peu sur la partie de code ci dessous.
En fait, avec ce code que j'ai récupéré, le serveur ecoute, quand un client se connecte, le serveur l'affiche, mais le client se déconnecte tout de suite après.

Bon j'ai en tout cas compris le systeme de fork, qui duplique le processus du serveur pour accepter les connexions, mais jvois pas comment jpourrais faire du pseudo evenementiel, une sorte de technique pour faire ce que je veux, sans forcément me montrer du code.
Genre, un serveur qui tourne, un client qu'on lance via mon_client <ip_du_serveur>, et une fois connecté on peut saisir et voir le texte des autres (un peu comme wall quoi..)

Bref, c'est pas très clair tout ca, et jvais surement me faire tapper sur les doigt par les raleurs, mais bon je tente le coup !

Ci joint le code a eclaircir, j'ai saisi la boucle infinie, mais le !fork dedans me perturbe, j'ai peur de pas trop comprendre.. :-\


Merci pour l'aide !



while(1) {

sin_size = sizeof(struct sockaddr_in);

if ((client_fd = accept(serveur_fd, (struct sockaddr *)&client_sock, &sin_size)) == -1) {

perror("Probleme avec la fonction accept()");
continue;
}

if (! fork()) {

/* Envoie du message au client */
if (send(client_fd, message, strlen(message), 0) == -1) {

perror("Probleme avec la fonction send()");
}
printf("Message envoye : %s\n", message);

/* Affichage du message envoyé par le client */
if ((nb_octets = recv(client_fd, tampon, 50, 0)) == -1) {

perror("Probleme avec la fonction recv()");
exit(EXIT_FAILURE);
}

tampon[nb_octets] = '\0';
printf("Message recu par le client %s : %s\n", inet_ntoa(client_sock.sin_addr), tampon);

close(client_fd);
}
close(client_fd);
}
  • # Re: Aide en C

    Posté par  . Évalué à 2.

    si c'est ce que que tu veux savoir :
    fork retourne 0 si c'est le fils, et le pid du fils si c'est le père.
    if (!fork ()) est donc vrai si c'est le fils (négation de 0).
    en fait il faudrait vérifier aussi que la valeur est différente de -1, qui signifie qu'il y a eut une erreur (dans ce cas errno est renseignée).
    dans le if (!fork()), on a donc le code de traitement de la connexion, qui se termine par une fermeture de la socket, donc une deconnexion du client, ce que tu ne veux pas.
    je te conseilles de regarder du coté des threads.
    • [^] # Re: Aide en C

      Posté par  . Évalué à 0.

      Les threads ? ok jv aller jetter un oeil la dessus.

      Mais ce serait possible de récuperer dans un tableau les pid de tout les fork, de facon a ce que quand un client envoi un message au serveur, le programme "serveur" réachemine le message vers tous les clients connectés ?
  • # Re: Aide en C

    Posté par  . Évalué à 2.

    Ca dépend. Si ton code est censé être un cas d'école impliquant toutes les techniques de base d'Unix et de l'informatique multitâches en général (fork, sockets, threads, etc.), c'est peut-être intérressant, mais si tu veux juste faire un daemon de broadcast qui retransmet à tout le monde ce que l'un des connectés écrit (un sorte de serveur IRC, quoi !), tu n'es pas obligé de forker pour chaque client. C'est même clairement déconseillé, parce que si tes clients sont nombreux, cela va faire pas mal de processus pour une application si basique.

    Regarde plutôt du coté de select(), qui permet d'attendre un événement sur un ou plusieurs descripteurs de fichiers ou sockets. En gros, tu fais une boucle infinie et tu colles ton select() en haut de cette boucle, ce qui va donc mettre ton système en attente jusqu'à ce qu'il se produise quelque chose. Dès lors, tu lis le messages reçu, tu le réécris sur tous les sockets ouverts, et tu reboucles. Bilan: 1 processus.
    • [^] # Re: Aide en C

      Posté par  . Évalué à 0.

      Oui voilà, c'est plutot ce genre de truc que je recherche !!

      Mais ca m'a l'air presque plus compliqué a manipuler que l'ouverture des sockets ca non ?

      En fait, je vois pas trop comment je pourrai, d'un coté faire une boucle infinie qui détecte les demande de connexions, et qui créér donc des socket en veux tu en voilà pour chaque client, et de l'autre une boucle infinie receptionnant les envois de données des clients

      J'ai en effet l'habitude des langages evenementiels, et des evenements tels que on_connect, on_data_receive, ou autres trucs du genre qui sont appelé dès que l'evenement se produit :-(

      Le code C qui est lu de haut en bas ca me perturbe j'ai pas l'habitude ! snif..


      Help !
      • [^] # Re: Aide en C

        Posté par  . Évalué à 1.

        Dans ce cas, tu peux effectivement créer un thread, ou même simplement forker en ouvrant un tube entre les deux processus (man 2 pipe). Le premier processus serait exclusivement chargé d'écouter le port concerné et de créer les nouvelles connexions, le second s'occupant du dispatch de tes informations.

        L'idée, c'est que ton premier processus prévient le second en envoyant un petit message dans le tube, exactement de la même manière que tes clients t'envoient des données à travers leur socket. Tu peux ainsi inventer tout un protocole entre les deux processus pour leur faire faire plein d'actions différentes, mais surtout tu peux ajouter le descripteur de ton tube avec ceux des sockets et filer le tout au même select.

        Ainsi, ton processus de dispatch sortira de sa léthargie sur n'importe quel type d'événement: réception de données en provenance des clients, ou du processus de connexion.

        Cela devrait suffire à implémenter ton système sans trop de soucis.
        Bon courage !

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.