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 de sockets POSIX


Sujet :

Réseau C

  1. #1
    Membre averti
    Inscrit en
    Décembre 2004
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 23
    Par défaut Problème de sockets POSIX
    Bonsoir tout le monde, voila que je m'interesse depuis pas longtemps aux sockets, mais je suis incapable de debugger un ptit chat très basique que je suis en train de faire. Ça me tourmente depuis plusieurs jours déjà.

    Le problème étant:

    1. Le serveur seulement reçoit le premier message envoyé par le client.
    2. Le client n'arrive à envoyer que 2 messages, après il plante ( sans erreurs ni seg fault...)

    Peut-être quelqu'un pourrait me dire ou se trouve l'erreur ou les erreurs ?

    Merci beaucoup, ci-dessous je cole le code:

    PS: Oui je suis espagnol
    ______________________________________________


    programilla-commons.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
    26
    27
    28
    29
    30
     
    #ifndef __PROGRAMILLA_COMMONS__
     
    #define __PROGRAMILLA_COMMONS__
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
     
    #define ERROR(numerror,errno) { printf("Error: %s // %s \n",
    errores[numerror-1], strerror (errno)); }
    #define SERVER_IP "127.0.0.1"
    #define SERVER_PORT 6969
    #define MAX 255
    #define LOG "mitxt"
    #endif
     
    char errores[10][45] = {"1, Apertura del fichero",
                           "2, Escritura del fichero",
                           "3, Cerradura del fichero",
                           "4, Lectura del mensaje en el socket",
                           "5, Escritura del mensaje en el socket",
                           "6, Apertura del socket del server",
                           "7, Publicidad del socket del server",
                           "8, Acceptar la conexion del cliente",
                           "9, Apertura del socket del cliente",
                           "10, Peticion de conexion del cliente"};
    programilla-cliente.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
     
    #include "programilla-commons.h"
     
    escribir_mensaje (int* socket_fd, char* mensaje)
    {
           int errno;
           int nbytes;
           if ((nbytes = send (*socket_fd, mensaje, MAX, 0)) == -1)
                   ERROR(5,errno);
           printf("Bytes escritos: %d , Mensaje = %s", nbytes, mensaje);
    }
     
    int main()
    {
           int errno;
           bool fin = false;
           FILE *txt;
           int socket_fd;
           char *mensaje = (char *) malloc (255);
           struct sockaddr_in server_addr;
     
           if ((socket_fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
                   ERROR(9,errno);
     
           server_addr.sin_family = AF_INET;
           server_addr.sin_addr.s_addr = inet_addr (SERVER_IP);
           server_addr.sin_port = htons (SERVER_PORT);
     
           if (connect (socket_fd, (struct sockaddr *) &server_addr, sizeof
    (server_addr)) == -1)
                   ERROR(10,errno);
     
           if ((txt = fopen (LOG, "w")) == NULL)
                   ERROR(1,errno);
     
           printf ("Introduce una linea (END para acabar)\n"); fflush (stdout);
           do {
                   fflush (stdout);
                   fgets (mensaje, MAX, stdin);
     
                   if ((strcmp (mensaje, "END\n")) == 0)
                   {
                           fin = true;
                           break;
                   }
     
                   if (fprintf (txt, mensaje) < 0)
                   {
                   ERROR(2,errno);
                   }
                   escribir_mensaje (&socket_fd, mensaje);
     
           }
           while (fin != true);
     
           if ((fclose (txt)) != 0)
                   ERROR(3,errno);
     
           free (mensaje);
           close (socket_fd);
     
    return 0;
     
     
    }

    programilla-server.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 "programilla-commons.h"
     
    leer_mensaje (int new_socket_fd, char* mensaje)
    {
           int errno;
           int nbytes;
           if (( nbytes = recv (new_socket_fd, mensaje, MAX, 0)) == -1)
                   ERROR(4,errno);
           printf(mensaje, nbytes);
    }
     
    int main()
    {
           int errno;
           int pid;
           int socket_fd, new_socket_fd;
           char *mensaje = (char *) malloc (255);
     
           struct sockaddr_in server_addr, client_addr;
     
           int client_addr_length;
     
           if ((socket_fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
                   ERROR(6,errno);
     
           server_addr.sin_family = AF_INET;
           server_addr.sin_addr.s_addr = inet_addr (SERVER_IP);
           server_addr.sin_port = htons (SERVER_PORT);
     
           if ((bind (socket_fd, (struct sockaddr *) &server_addr, sizeof (server_addr))) == -1)
                   ERROR(7,errno);
     
           listen (socket_fd, 5);
     
           for (;;) {
                   client_addr_length = sizeof (client_addr);
     
                   if ((new_socket_fd = accept (socket_fd, (struct sockaddr *) &client_addr, &client_addr_length)) == -1)
                           ERROR(8,errno);
     
                   if ((pid = fork ()) == -1)
                   {
                           ERROR(15,errno)
                   }
                   else if (pid == 0) {
                           close (socket_fd);
                           leer_mensaje (new_socket_fd, mensaje);
                           close (new_socket_fd);
                           exit (0);
                   }
                           close (new_socket_fd);
           }
     
     
    return 0;
     
    }

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Par défaut
    Citation Envoyé par shuygar
    Bonsoir tout le monde, voila que je m'interesse depuis pas longtemps aux sockets, mais je suis incapable de debugger un ptit chat très basique que je suis en train de faire. Ça me tourmente depuis plusieurs jours déjà.

    Le problème étant:

    1. Le serveur seulement reçoit le premier message envoyé par le client.
    2. Le client n'arrive à envoyer que 2 messages, après il plante ( sans erreurs ni seg fault...)

    Peut-être quelqu'un pourrait me dire ou se trouve l'erreur ou les erreurs ?

    Merci beaucoup, ci-dessous je cole le code:

    PS: Oui je suis espagnol
    Bonsoir à tous nos amis espagnols (et à tous les autres aussi, il n'y a pas de raison) !

    Si j'ai bien lu ton code :
    - ce que tu appelles "message" ("mensaje") est censé être une ligne de texte (attention aux termes que tu utilises, cela peut être trompeur) ;
    - le client se connecte une fois et peut envoyer plusieurs "messages" en utilisant la même connexion ;
    - le serveur, pour chaque connexion acceptée, n'appelle "leer_mensaje (new_socket_fd, mensaje);" qu'une seule fois.

    Déjà, là, tu dois comprendre une partie du problème.

    Une autre chose à laquelle tu dois penser : 1 send() sur une machine n'est pas forcément équivalent à 1 recv() sur l'autre machine.
    Autrement dit : il faut appeler recv() jusqu'à ce qu'il n'y ait plus rien à lire.

    Concernant le plantage du client, tu nous dis "il plante ( sans erreurs ni seg fault...)"...ok...mais avec quoi ? Rien ? A quel endroit ? Que veux-tu dire par "plante" : le client s'arrête/quitte ou semble se bloquer et attendre ?

    Aussi, même si cela n'a pas forcément de rapport avec ta question :
    - essaye de prendre l'habitude de toujours spécifier une chaîne de format avec les fonctions *printf() (si tu ne sais pas pourquoi, cherche "format string vulnerability" avec ton moteur de recherche préféré) ;
    - tes fonction "escribir_mensaje()" et "leer_mensaje()" devraient renvoyer une valeur pour indiquer si elles ont réussi ou pas ;
    - personnellement, j'écrirai plutôt les erreurs sur stderr.

    En espérant que cela puisse t'aider...

  3. #3
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Des warnings un peu dangereux...

    programilla-server.c:4: warning: return type defaults to ‘int’
    programilla-server.c: In function ‘leer_mensaje’:
    programilla-server.c:10: warning: control reaches end of non-void function
    programilla-server.c: In function ‘main’:
    programilla-server.c:27: warning: implicit declaration of function ‘inet_addr’
    programilla-server.c:38: warning: pointer targets in passing argument 3 of ‘accept’ differ in signedness
    programilla-server.c:41: warning: implicit declaration of function ‘fork’
    programilla-server.c:46: warning: implicit declaration of function ‘close’
    et

    programilla-client.c: In function ‘escribir_mensaje’:
    programilla-client.c:10: warning: control reaches end of non-void function
    programilla-client.c: In function ‘main’:
    programilla-client.c:25: warning: implicit declaration of function ‘inet_addr’
    programilla-client.c:59: warning: implicit declaration of function ‘close’
    - Ensuite, pour le serveur, le problème c'est que tu ne fais qu'un seul recv avant de quitter ton programme... Il faudrait mettre une boucle dans ta fonction leer_mesaje

    -En passant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf(mensaje, nbytes);
    Je ne vois pas l'utilité de passer nbytes...

    - Pour l'erreur du client, cela était une conséquence de l'erreur du serveur...

    Jc

  4. #4
    Membre averti
    Inscrit en
    Décembre 2004
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 23
    Par défaut
    Citation Envoyé par fearyourself
    Des warnings un peu dangereux...



    et



    - Ensuite, pour le serveur, le problème c'est que tu ne fais qu'un seul recv avant de quitter ton programme... Il faudrait mettre une boucle dans ta fonction leer_mesaje

    -En passant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf(mensaje, nbytes);
    Je ne vois pas l'utilité de passer nbytes...

    - Pour l'erreur du client, cela était une conséquence de l'erreur du serveur...

    Jc
    Ahhh merde, donc faut une boucle juste pour le recv, moi je croyait qu'a chaque envoi de paquet il fallait appeller la fonction accept(), et c'est pour cela que j'englobait tout dans un seul for.

    Sinon pour nbytes c'était juste un printf() pour le débuggage, rien d'important.

    Grand merci, ça commençait à me tapper sur le systeme

    J'oubliai, quels arguments tu passe a GCC pour voir ces warnings ? Merci encore

  5. #5
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par shuygar
    J'oubliai, quels arguments tu passe a GCC pour voir ces warnings ? Merci encore
    -Wall -Wextra

    Me suffisent généralement, sinon je prends les 3 lignes de warnings d'Emmanuel (suffit de chercher dans le forum... ) quand je suis vraiment à la recherche d'un bon code bien sûr...

    Jc

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Par défaut
    Citation Envoyé par shuygar
    J'oubliai, quels arguments tu passe a GCC pour voir ces warnings ?
    En plus de -Wall, essayes d'ajouter -Wextra si ta version de gcc le supporte. Sinon, il y en a toute une série qui ne sont pas forcément inclus dans le trompeur -Wall (implicit/return-type/unused/switch/uninitialized/...)...voir la doc

    Mince : m'afédoublé

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Je n'ai pas la liste de warnings d'Emmanuel, mais je suis pour ajouter -Wwrite-strings en plus de -Wall -Wextra (+ une option d'optimisation genre -O2, car certains warnings ne sont pas affichés si le compilo n'essaie pas d'optimiser).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Problème de sockets
    Par the_penguin dans le forum Réseau
    Réponses: 8
    Dernier message: 13/04/2006, 19h19
  2. Problême de Socket avec un applet java (RMI/policy)
    Par Vesperal dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 12/04/2006, 12h00
  3. Réponses: 2
    Dernier message: 26/03/2004, 09h15
  4. [Kylix] Problème de socket
    Par RaygKross dans le forum EDI
    Réponses: 1
    Dernier message: 01/03/2004, 19h41
  5. Mysql ne se lance pas problème de socket
    Par Riko dans le forum Installation
    Réponses: 5
    Dernier message: 05/02/2004, 09h28

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