Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème socket et chaine de caractère

    23 novembre 2017 à 22:05:06

    Bonjour,

    J'aurais besoin d'un peu d'aide concernant mon programme. J'essaye de faire communiquer un client avec un serveur avec des sockets. La communication marche bien, mais le problème vient d'une chaine de caractère. Quand j'envoie un premier message, pas de problème. Si j'envoie un deuxième message avec une longueur inférieur au premier message, il garde la fin du message précédent ... 

    Exemple :

    Je voudrais qu'il affiche "Ok" et pas "Oklut".

    Voici le code :

    Client.c

    #include<stdio.h>
    #include<string.h>
    #include<sys/socket.h>
    #include<arpa/inet.h>
    
    void LireChaine(char[], int);
    
    int main(int argc , char *argv[])
    {
        int sock;
        struct sockaddr_in server;
        char message[1000] , server_reply[1000];
         
        //Création de la socket
        sock = socket(AF_INET , SOCK_STREAM , 0);
        if (sock == -1)
        {
            printf("Impossible de créer la socket");
        }
        puts("Socket créée");
         
        server.sin_addr.s_addr = inet_addr("127.0.0.1");
        server.sin_family = AF_INET;
        server.sin_port = htons( 5000 );
     
        //Connexion serveur
        if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
        {
            perror("Connexion impossible");
            return 1;
        }
         
        puts("Connecté\n");
         
        //Communication avec le serveur
        while(1)
        {
        
            printf("Entrez votre message : ");
            LireChaine(message, 1000);
             
            //Envoyer des messages
            if( send(sock , message , strlen(message) , 0) < 0)
            {
                puts("Erreur Send");
                return 1;
            }
             
            //Recevoir des messages de la part du serveur
            if( recv(sock , server_reply , 1000 , 0) < 0)
            {
                puts("Erreur recv");
                break;
            }
             
            puts("Réponse du serveur :");
            puts(server_reply);
     
    
        }
         
        close(sock);
        return 0;
    }
    
    void LireChaine(char chaine[], int size) {
    	fgets(chaine, size, stdin);
    	chaine[strlen(chaine) - 1] = '\0';
    }

    Server.c

    #include<stdio.h>
    #include<string.h>    
    #include<sys/socket.h>
    #include<arpa/inet.h> 
    #include<unistd.h>   
    #include <stdlib.h>
     
    int main(int argc , char *argv[])
    {
        int socket_desc , client_sock , c , read_size;
        struct sockaddr_in server , client;
        char client_message[1000];
         
        //Création socket
        socket_desc = socket(AF_INET , SOCK_STREAM , 0);
        if (socket_desc == -1)
        {
            printf("Impossible de créer la socket");
        }
        puts("Socket créée");
         
        //Structure sockaddr_in 
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port = htons( 5000 );
         
        //Bind
        if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
        {
            perror("Erreur bind");
            return 1;
        }
        puts("bind OK");
         
        //Ecoute
        listen(socket_desc , 3);
         
        puts("Waiting for incoming connections...");
        c = sizeof(struct sockaddr_in);
         
        //Acceptation connexion client
        client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
        if (client_sock < 0)
        {
            perror("Erreur accept");
            return 1;
        }
        puts("Connexion acceptée");
        
        //Lire message du client
        while( (read_size = recv(client_sock , client_message , 1000 , 0)) > 0 )
        {
            write(client_sock , mesg , strlen(client_message));
        }
         
        if(read_size == 0)
        {
            puts("Client déconnecté");
            fflush(stdout);
        }
        else if(read_size == -1)
        {
            perror("Erreur recv");
        }
         
        return 0;
    }

    Merci d'avance.



    • Partager sur Facebook
    • Partager sur Twitter
      23 novembre 2017 à 23:09:37

      Hello,

      Pour éviter ce problème, j'emploie une fonction home made à la place de strlen: strzlen. C'est tout con, c'est

      size_t strzlen(char *str) {
          return(strlen(str)+1);
      }

      Ça permet d'envoyer le \0, et d'éviter l'affichage que tu as.

      Et pour éviter le \n que fgets() inclut dans le string lu:

      char *s;
      
      if(strrchr(str,'\n')!=NULL)
          *(strrchr(str,'\n')=0;

      (il y a plusieurs variante à cette idée)

      -
      Edité par edgarjacobs 23 novembre 2017 à 23:12:22

      • Partager sur Facebook
      • Partager sur Twitter

      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

        24 novembre 2017 à 8:06:23

        Bonjour, 

        Je test votre solution ce soir et je vous tiens au courant.

        • Partager sur Facebook
        • Partager sur Twitter
          25 novembre 2017 à 16:22:51

          Bonjour,

          Votre solution avec strzlen marche. Merci beaucoup !

          Je voudrais maintenant faire en sorte que plusieurs clients puissent communiquer dans ce chat. Je sais qu'il faut utiliser les threads, mais comment je pourrais envoyer un message d'un client reçu par le serveur à tous les clients ? Je voudrais aussi gérer les pseudos des clients.

          Merci,

          • Partager sur Facebook
          • Partager sur Twitter
            28 novembre 2017 à 21:26:07

            Bonjour,

            Quelqu'un aurait une réponse à me donner svp ?

            J'avais pensé à mettre les utilisateurs dans un tableau, mais comment gérer les pseudos et envoyer le message à tous les utilisateurs avec le pseudo.

            Merci

            • Partager sur Facebook
            • Partager sur Twitter
              29 novembre 2017 à 10:53:19

              Les exemples de chats multiclients ne manquent pas sur google...

              Il vous faut enregistrer chaque nouveau client dans une liste/tableau et a chaque nouveau message, vous reexpedier a toute la liste.

              Après, par client, c'est pas juste son socket, cela peut etre une structure contenat tous les champs dont vous pensez avoir besoin.;

              Avez vous de l'imagination? Savez vous analyser les exemples existant? Cela va vous demander du travail personnel de compréhension puis de conception.

              -
              Edité par breizhbugs 29 novembre 2017 à 10:53:51

              • Partager sur Facebook
              • Partager sur Twitter
              ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
                29 novembre 2017 à 12:41:15

                SnSn a écrit:

                Je sais qu'il faut utiliser les threads

                Non et c'est même une mauvaise idée. Il existe des manières bien plus simple de faire ça (poll).

                -
                Edité par Mad scientist 29 novembre 2017 à 12:41:38

                • Partager sur Facebook
                • Partager sur Twitter
                Un vrai cours de: (C | C++ | Haskell débutant | Haskell intermédiaire | Rust).

                Problème socket et chaine de caractère

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown