Annonce

Réduire
Aucune annonce.

[RE] Mini chat en C ! (avec les sockets !)

Réduire
X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • [RE] Mini chat en C ! (avec les sockets !)

    Salut à tous ! J'ai finalement décidé de progresser avec les sockets en C (le début du tuto était vraiment lent et ennuyant mais j'ai finalement percé )

    J'ai donc décidé de faire un mini chat ! (j'ai vu qu'il y avait un sujet dessus mais le code était vraiment différent et beaucoup plus compliqué :s

    Bref, j'ai fait en sorte d'être le plus clair parce que lire et corriger un code concernant les sockets n'est JAMAIS amusant ou facile !

    Côté serveur !

    Code:
    int main (void)
    {
        // Je déclare mes variables !
        SOCKET Masock;
        SOCKADDR_IN Monaddresse;
        
        SOCKET clientsock;
        SOCKADDR_IN clientaddresse;
    
        char message[200] = "Connexion etablie !!!";
        char clientmessage[200]="";
    
        int taille=sizeof(Monaddresse);
        int tailleclient = sizeof(clientaddresse);
    
        int erreur=0;
        int    i=1;
        // fin de la déclaration !
    
        Masock = socket(AF_INET, SOCK_STREAM, 0); //création de la socket 
         if(Masock != INVALID_SOCKET)
         {
            //configuration de la socket
            Monaddresse.sin_addr.s_addr    = htonl(INADDR_ANY);
            Monaddresse.sin_family         = AF_INET;
            Monaddresse.sin_port           = htons(23);
            erreur= bind(Masock, (SOCKADDR*)&Monaddresse,taille); 
            
               //fini !
    
            if(erreur!= SOCKET_ERROR)
            {
    
                erreur= listen(Masock, 5); 
                if(erreur!= SOCKET_ERROR)
                {
    
                   // on attends que quelqu'un se connecte :p 
                    clientsock = accept(Masock, (SOCKADDR*)&clientaddresse, &tailleclient);
                   // quelqu'un s'est connecté ! :D
    
    
                        if(erreur!= SOCKET_ERROR)
                         {
                            while(i)
                            {
                            send(clientsock, message, 200, 0); //j'envoie le message: "connexion établie !"
                            printf("Chaine envoyee : %s\n\n", message);  
                            lire(message,200); //un simple gets amélioré (je demande ce que je veux envoyer au client ensuite)                           
    
     /* je ne peux recevoir un message qu'après en avoir envoyé un, mais ce n'est pas le problème pour                                                 le  moment*/
                                if(recv(Masock, clientmessage, 200, 0) != SOCKET_ERROR) 
                                    {
                                        printf("Recu : %s \n",clientmessage);
                                    }
                              
                            
                            }
    Bon, ce code est plutôt simple, je l'ai simplifié au maximum !

    Côté client !

    Code:
    int main(void)
    {
    //déclaration des variables !   
        int i=1;
        SOCKET serversock;
        SOCKADDR_IN serveraddr;
        SOCKET Masock;
        SOCKADDR_IN Masin;
        char buffer[200] = "";
        char message[200]="connexion etablie avec le serveur";
    // fin de la déclaration des variables
        
            sock = socket(AF_INET, SOCK_STREAM, 0);
    
            sin.sin_addr.s_addr = inet_addr("127.0.0.1");
            sin.sin_family = AF_INET;
            sin.sin_port = htons(PORT);
    // pas de bind car c'est le client :p
    
            if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) // on essaye de se connecter !
            {
                while(i)
                {
                 
                if(recv(sock, buffer, 200, 0) != SOCKET_ERROR)
                        {
                                printf("Recu : %s \n", buffer); // on affiche ce que l'on reçoit
                        }
    
                erreur= send(serversock, message, 200, 0); //l'erreur est ici je suppose.
                        
    
                        if(erreur)/*La fonction retourne SOCKET_ERROR en cas d'erreur, sinon elle retourne le nombre d'octets envoyés.*/
                        {
                                printf("NOMBRE D OCTET ENVOYES: %d\n",erreur);
                        }
                        printf("Chaine envoyee : %s\n\n", message); // on montre ce qu'on a envoyé.
    
                        
                        lire(message,200); // on demande ce que l'utilisateur veut envoyer.
                }
            }
    voila a quoi ressemble un echange.
    Capture.jpg

    Ce serait vraiment génial si quelqu'un pourrait me dire quel est le problème !
    Le monde est dévoré par l’ennui.

  • #2
    Salut luffreezz,

    J'ai moi-même réaliser ce genre de petit projet et j'espère qu'il t'apportera autant.

    Concernant le code, tu oublis d'appeler la fonction " getaddrinfo() " qui te permettra d'obtenir une "struct addrinfo" avec toutes informations don tu as besoin.

    Je pourrais aussi te conseiller d'utiliser des arguments pour avoir un programme un peu plus modulable :

    Code:
    ./client <adresse_ip> <port>
    Petite astuce au niveau de ton " accept() ", si tu veux pouvoir gérer plusieurs connexions, utilise la fonction " fork() " (création du processus fils) :

    Code:
     while( 1 == 1 ) {
    
            SockCOM = accept( SockRDV, ( struct sockaddr * ) &from, &len );
    
            if( ( pid= fork() ) == 0) {
    
                close( SockRDV );  // On ferme le socketRDV on s'occupe seulement de gérer le socket actuel
    Lorsque tu envois des String, tu as bien penser a bien les formatées, c'est-à-dire <String>+<\n>+<'\0'> ?

    Code:
    erreur= send(serversock, message, 200, 0); //l'erreur est ici je suppose.
    En effet, le nom du socket me paraît pas bon,plutôt " sock "

    Bon courage !

    Hésites pas si tu as d'autres questions.
    deux et deux font cinq

    Commentaire


    • #3
      Shirocen merci énormément !! ça fait vraiment plaisir d'avoir des réponses !

      Désolé pour l'ancien screen qui n'est pas clair du tout, j'en ai fait un autre du cas actuel avec gyazo, j'espère que vous verrez mieux.

      https://gyazo.com/e037a3f1567453d64824b672cfb20303

      En gros, le client envoie des messages mais le serveur ne les reçoit pas.

      Côté serveur
      Code:
      if(recv(Masock, clientmessage, 200, 0) != SOCKET_ERROR) 
                                      {
                                          printf("Recu : %s \n",clientmessage);
                                      }
      Côté client
      Code:
      if(recv(sock, buffer, 200, 0) != SOCKET_ERROR)
                          {
                                  printf("Recu : %s \n", buffer); // on affiche ce que l'on reçoit
                          }
      Bon ici le code est exactement le même. Faut voir un peu plus haut je suppose.

      Euhm.
      Code:
       char buffer[200] = "";
      Code:
          char clientmessage[200]="";
      C'est la même chose ici aussi.

      Peut être c'est parce que le client ne sais pas ou envoyer le message mais il l'envoie quand même ?

      Je sais pas du tout. Si quelqu'un pourrait m'aider ? ce serait super cool !
      Le monde est dévoré par l’ennui.

      Commentaire


      • #4
        Proposes nous tes codes en entier pour qu'on puisse avoir tous les éléments pour t'aider.

        Un lien pastebin pas exemple !
        deux et deux font cinq

        Commentaire


        • #5
          Ouais bien sûr ! voilà les 2 codes en entier !

          http://pastebin.com/1SpV6CKu
          Le monde est dévoré par l’ennui.

          Commentaire


          • #6
            Tu ne devrais pas être loin de la vérité, tu oublis d'utiliser getaddrinfo() qui te fournira une adresse de type addrinfo

            utilisable par les fonctions bind et connect.
            deux et deux font cinq

            Commentaire


            • #7
              Sur Windows, il y a quand même pas mal de possibilité d'erreurs lors de l'initialisation de la DLL via WSAStartup... Tu devrais tout de même vérifier que ça se passe bien de ce côté avant même de commencer quoi que se soit.

              Commentaire


              • #8
                Plusieurs points auxquels je rejoint Fred. Les libs que tu utilisent sont elles bien adaptés à ton programme. Lorsque je lis ton programme tu indique l'utilisation de "ws2_32.lib" et de la version 2.2 de winsock (MAKAWORD (2.2)), là à toi de vérifier car je ne sais pas ce que tu a mis sur ton PC.

                Un deuxième point sur #include "biblio.h", c'est un module que tu a créé, je ne connais pas ? Si c'est le cas le code est où ?

                3e point, tu a déclaré ton IP local mais le port, il est déclaré où ? sin.sin_port = htons(PORT);

                Tu ne précise pas PORT ? Je pense que ce n'est pas la peine mais jne pourrais t-il pas y avoir un conflit ?

                Je continue d'analyser et d'essayer de comprendre ton code désolé pour les questions mais c'est difficile pour moi le C (c'est vieux et j'ai toujours été un peu le canard boiteux dans ce code) ^^

                J'éditerais au fur et à mesure que je trouve des incohérences ou des questions même stupide afin de comprendre ton raisonnement.

                Cette partie :
                printf("Connection a %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));

                printf("Connection a %s sur le port %d\n", IP, PORT);

                Non ? D'où tu sort inet_ntoa(sin.sin_addr), moi je n'ai sur ton script que : sin.sin_addr.s_addr = inet_addr("127.0.0.1");

                Explique moi car je suis largué sur des points, pourtant le script entier ne fait qu'une page ^^

                Et ça c'est quoi ??? lire(message,200); Je ne connais pas cette fonction, elle est déclaré où ? Sur ton fichier module biblio ?

                Ok je viens de voir que le PORT est déclaré sur le serveur ^^ Faut que j'ouvre les yeux. ?

                Tous les ports qui reçoivent les paquets transmis doivent être redirigés localement. Sinon le routeur ne peut pas savoir à quel PC du réseau local sont destinées les données qui arrivent sur le port.
                Là tu utilise telnet le port 23. Essais avec un autre port.

                J'essais de comprendre ton programme, j'essais d'analyser les points importants mais surtout suivant la procèdure de transmission du message qui sont des paquets redirigés via une IP et un port, il vont être défragmentés puis refragmentés sur le serveur. Si la connection est bonne mais les paquets n'ont pas aboutis c'est qu'il y a une perte des données. Dans ton cas, utilisant TCP (23) le flot d’octets est bufferisé en segments (d'où l'utilisation de buffer).


                Une question ? pourquoi a tu préféré closesocket(sock); à close(sock); ?
                Dernière modification par DreAmuS, 13 février 2016, 15h52.

                Commentaire

                Chargement...
                X