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 :

socket : envois des donn�es impossible


Sujet :

R�seau C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Par d�faut socket : envois des donn�es impossible
    Bonjour,

    D�cidement les sockets �a ne r�ussit pas � tout le monde !
    Je tente de cr�er un programme (client/serveur) de chat tr�s basique juste pour me familiariser avec les sockets sous windows.
    Mon code se compile sans erreur mais je ne parvient pas � envoyer de donn�es. Voici mon code source :

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    #include <stdio.h>
    #include <winsock2.h>
    #include <string.h>
     
     
     
    main(void)
    {
     
          WSADATA WSAData; // Initialisation des variables
     
          int start_wsa; 
     
          int serveur_socket, client_socket;
          struct sockaddr_in  ip_serveur, ip_client;
          int port = 1000;
          int ip_serveur_size;
     
          int envoyer, recevoir;
          char *message;
          char buffer[512];
          int rec;
     
          start_wsa = 1; 
     
     
          if((start_wsa = WSAStartup(MAKEWORD(2,0), &WSAData)) != 0) {               
                  printf("Erreur : Initialisation de winsock impossible \n");
                  return 0;               }
     
          memset(&ip_serveur, 0, sizeof(ip_serveur));               
     
          ip_serveur.sin_addr.s_addr = htons(INADDR_ANY); 
          ip_serveur.sin_family = AF_INET; 
          ip_serveur.sin_port = htons(port);             
     
          if((serveur_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){ 
                  printf("Erreur : Création de la  socket impossible \n");
                  return 0; 
                  }
     
     
          bind(serveur_socket, (struct sockaddr *)&ip_serveur, sizeof(ip_serveur));     
     
          listen(serveur_socket, 0); 
     
          ip_serveur_size = sizeof(ip_client);
     
          if((client_socket = accept(serveur_socket,
                             (struct sockaddr *)&ip_client,
                             &ip_serveur_size)) == -1) { 
                   printf("Erreur : Connexion avec le client impossible\n");
                   return 0;
                   }
     
          printf("Connecte a l'hote\n");
          printf("Tapez votre message\n\n");
     
     
          do
          {
     
          scanf("%s", buffer);
     
          if ((envoyer = write(client_socket,buffer, 512)) == -1) {
                 printf("Erreur : Envoi de \"%s\" impossible", buffer);
                 return 0;
                 }  
     
          if ((recevoir = read(client_socket,buffer, 512)) == -1) {
                  printf("Erreur : Reception des donnees impossible");
                  return 0;       
                  }   
     
          printf("Client : %s\n", buffer);        
     
                }
          while (start_wsa > 0);
     
          return 0;
    }
    Mon programme n'est pas termin�, je souhaitais juste le tester avant de passer aux finitions.
    Je pr�cise que j'utilise "netcat" pour le tester n'aillant pas encore coder le client.

    Merci d'avance !

  2. #2
    Membre �m�rite
    Avatar de Freed0
    Profil pro
    �tudiant
    Inscrit en
    Mars 2005
    Messages
    635
    D�tails du profil
    Informations personnelles :
    �ge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Par d�faut
    J'ai trouv� quelques erreurs :

    La fonction utilis�e pour d�finir l'adresse IP est htonl (host to network long) et non htons (host to network short). L'ip est de type long.

    Autre erreur, d�finis le type de main Utilise int main(void) ce qui est le plus pratique (surtout que dans ton code tu renvoies une valeur !).

    Le premier argument de socket() est PF_INET (protocol family) et non AF_INET (address family). Ce dernier est juste utilis� par sin_family.

    On utilise les fonction send et recv et non write et read.

    Oublie pas WSACleanup � la fin de ton programme

    Voil� c'est fini, bonne continuation

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Par d�faut
    Bonjour,

    Apr�s quelques modifications, selon certains de tes conseils, le serveur fonctionne !
    Il me reste un probl�me a r�gler, je ne peux qu'envoyer un seul mot � la fois, quand j'ins�re un espace seul le premier mot est transmit. Les autres mots de la phrase ne sont visibles qu'en appuyant sur entr�e (r�ex�cution de la boucle)
    Comment rem�dier � cela ?

    merci

  4. #4
    Membre �m�rite
    Avatar de Freed0
    Profil pro
    �tudiant
    Inscrit en
    Mars 2005
    Messages
    635
    D�tails du profil
    Informations personnelles :
    �ge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Par d�faut
    Ca doit �tre ta boucle do while qui pose probl�me.
    Mets une boucle infinie (while(1)) pour voir ce que ca donne.

    Sinon utilise fgets au lieu de scanf, c'est mieux

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Par d�faut
    Oui je n'ai pas repost� mon code, mais j'avais d�j� modifier cette boucle par une boucle while v�rifiant la validit� du socket ...
    fgets ? Je ne connais pas, on l'emplois comment ?

    EDIT : fgets c'est pas plut�t pour �crire dans un fichier ? Je pense qu'ici gets() suffit non?

    ++

  6. #6
    Membre �m�rite
    Avatar de Freed0
    Profil pro
    �tudiant
    Inscrit en
    Mars 2005
    Messages
    635
    D�tails du profil
    Informations personnelles :
    �ge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Par d�faut
    fgets permet entre-autre de lire dans un fichier, mais il permet aussi la saisie de donn�es :

    fgets(message, sizeof(message), stdin);



    http://emmanuel-delahaye.developpez....tes.htm#saisie

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Par d�faut
    D'accord si j'ai bien compris gets() est obsol�te ... autant pour moi !
    J'ai modifi� mon code, et cela fonctionne � merveille !
    Il ne me reste le client � coder, et pas mal de d�tails � fignoler

    Merci encore !

  8. #8
    Membre �m�rite
    Avatar de Freed0
    Profil pro
    �tudiant
    Inscrit en
    Mars 2005
    Messages
    635
    D�tails du profil
    Informations personnelles :
    �ge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Par d�faut
    Aucun probl�me
    Si jamais t'as du temps � perdre, je suis en train de cr�er une page d'aide sur les sockets :

    http://tera-hardware.be/test/

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Par d�faut
    Salut,

    �a ne sera pas du temps perdu, je vais lire �a d�s que j'en aurais le temps !
    Petite question � la vol�e : l'h�te d�s qu'il est connect� au serveur doit attendre un message de ce dernier, je peux biens�r faire l'inverse, mais serait-il possible qu'il n'y ait plus d'ordre d�fini ? Quelle algo utiliser ?

    Merci

  10. #10
    Membre �m�rite
    Avatar de Freed0
    Profil pro
    �tudiant
    Inscrit en
    Mars 2005
    Messages
    635
    D�tails du profil
    Informations personnelles :
    �ge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Par d�faut
    Peut-�tre faire un send et un recv ?

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Par d�faut
    Autre chose, pour qu'il n'y ait pas d'�rreurs, possible j'ai cr�� deux buffers distincts un pour envoyer l'autre pour recevoir...

    Pour faire un send et recv en m�me temps �a serait du type
    if (envoyer = send... == -1 && recv... ==-1)
    { traitement de l'�rreur }

    instructions suivantes

    Une simple combinaison des deux en fait non ?
    ++

  12. #12
    Expert �minent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retrait�
    Inscrit en
    D�cembre 2003
    Messages
    14 512
    D�tails du profil
    Informations personnelles :
    �ge : 69
    Localisation : France, Paris (�le de France)

    Informations professionnelles :
    Activit� : Retrait�

    Informations forums :
    Inscription : D�cembre 2003
    Messages : 14 512
    Par d�faut
    Citation Envoy� par thechief
    Autre chose, pour qu'il n'y ait pas d'�rreurs, possible j'ai cr�� deux buffers distincts un pour envoyer l'autre pour recevoir...
    Oui, �l�mentaire...
    Pour faire un send et recv en m�me temps �a serait du type
    Il vaut mieux un thread pour la r�ception...

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Par d�faut
    Il vaut mieux un thread pour la r�ception...
    Je n'y connais rien aux threads. Je sais juste qu'un thread est une sorte sous-processus, c'est vague... mais je peux apprendre. L'utilit� d'un thread ici serait donc d'avoir ma boucle (quasi infinie) d'envois de donn�es et en m�me gr�ce au thread de pouvoir recevoir les donn�es ? Corrigez-moi si je me trompe je suis d�butant.

    Autre chose, j'ai commenc� la programmation du client et l� nouveau probl�me de logique, pas d'erreur de syntaxes mais �a ne fonctionne pas

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    #include <winsock2.h>
    #include <stdio.h>
    #include <string.h>
     
     
    main(void) {
     
          WSADATA WSAData; //initiation des variables
          int start_wsa;
     
          int socket_c;
          struct sockaddr_in adresse;
          int port = 1000; // Port de connexion
          char buffer_ip[16]; // Buffer adresse ip
     
          int envoyer, recevoir;
          char buffer_send[512]; // Buffer d'envoi
          char buffer_recv[512]; // Buffer de reception
     
     
          if((start_wsa = WSAStartup(MAKEWORD(2,0), &WSAData)) != 0) {  // Initialisation de la dll Winsock
                  printf("Erreur : Initialisation de winsock impossible \n");
                  return 0; // Si erreur fin d'éxécution du programme
                  }
     
         if((socket_c = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){ // Création de la socket
                  printf("Erreur : Création de la  socket impossible \n");
                  return 0; // Si erreur fin d'éxécution du programme
                  }
     
     
         printf("Entrez l'adresse du serveur, exemple : XXX.XXX.XXX.XXX\n\n"); // Entrez l'adresse du serveur
          scanf("%s", buffer_ip);
          printf("Connexion ...\n\n");
     
          adresse.sin_addr.s_addr = inet_addr(buffer_ip);
          adresse.sin_family    = AF_INET;
          adresse.sin_port    = htons(port);
     
          int adresse_size = sizeof(adresse);
     
          if((socket_c = accept(socket_c,(struct sockaddr *)&adresse, &adresse_size)) == -1) { // Connexion avec le serveur
                   printf("Erreur : Connexion avec le serveur impossible\n");
                   return 0;
                   }
     
          printf("Connecte au serveur\n");
          printf("En attente d'un message\n\n");
     
     
          while(socket_c != INVALID_SOCKET)
          {
     
          if((recevoir =  recv(socket_c, buffer_recv,512,0)) != SOCKET_ERROR) // Reception des données
               {
                      printf("%s\n", buffer_recv);
               }
     
          fgets(buffer_send, sizeof(buffer_send), stdin);
     
          if ((envoyer = send(socket_c, buffer_send, strlen(buffer_send), 0)) != strlen(buffer_send)){ // Envoyer les données
             printf("Erreur : Envois des données impossible\n");
             return 0;
             }
     
          }
     
          shutdown(socket_c, 2);
          close(socket_c, 2);
          WSACleanup();
          return 0;
     
     
           }
    Je me suis dit que �a bugg� peut-�tre au niveau de mon scanf() pour l'adresse... c'est fort possible, mais quand je fourni l'adresse ip directement :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    adresse.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    �a ne fonctionne pas non plus, j'ai relus mainte et mainte fois mon code, je ne trouve rien.

    merci

  14. #14
    zul
    zul est d�connect�
    Membre chevronn� Avatar de zul
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    498
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 498
    Par d�faut
    Pour le client, il faut utiliser connect et pas accept.

    Pour le serveur, il faudrait tester les valeurs de retour de bind et de listen , et afficher des messages d'erreurs significations ( avec WSAGetLastError ).

    Quand tu nous dis "ca ne marche pas'", peut-etre pourrait tu etre un peu plus precis sur l'endroit ou le code echoue ( les printf doivent servir a ca je suppose ). Au passage, il faut mieux utiliser stderr que stdout quoi que je doute que cela change grand chose sous Windows.

  15. #15