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
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 5
    Points
    5
    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 éprouvé
    Avatar de Freed0
    Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    635
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Points : 953
    Points
    953
    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
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 5
    Points
    5
    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 éprouvé
    Avatar de Freed0
    Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    635
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Points : 953
    Points
    953
    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
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 5
    Points
    5
    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 éprouvé
    Avatar de Freed0
    Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    635
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Points : 953
    Points
    953
    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
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 5
    Points
    5
    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 éprouvé
    Avatar de Freed0
    Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    635
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Points : 953
    Points
    953
    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
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 5
    Points
    5
    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 éprouvé
    Avatar de Freed0
    Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    635
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

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

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 5
    Points
    5
    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 sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    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...
    Pas de Wi-Fi à la maison : CPL

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 5
    Points
    5
    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 éclairé 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
    Points : 699
    Points
    699
    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
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 5
    Points
    5
    Par défaut
    Entre temps je me suis rendu compte de mon érreur, il fallait biensûr utiliser connect() et non accept(). Je parviens donc à me connecter au serveur. Mais les problèmes s'enchainent.
    La reception de données en provenance du serveur échoue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if((recevoir =  recv(socket_c, buffer_recv,512,0)) != SOCKET_ERROR) // Reception des données
    J'ai ajouté ces deux lignes afin de purger le tampon du clavier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int c;
          while ((c = getchar()) != '\n' && c != EOF); /* purge du tampon */
    Sans lequelles je n'ai pas accès à la fonction fgets()
    D'ou vient ce problème ? Est-ce du à la fonction scanf() utilisée plus haut ?
    Quoiqu'il en soit l'envois de données échoue lui aussi.
    Donc la connexion est établie mais je ne parvient à aucun échanges...

    ++

  16. #16
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par thechief
    J'ai ajouté ces deux lignes afin de purger le tampon du clavier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int c;
          while ((c = getchar()) != '\n' && c != EOF); /* purge du tampon */
    Sans lequelles je n'ai pas accès à la fonction fgets()
    D'ou vient ce problème ? Est-ce du à la fonction scanf() utilisée plus haut ?
    Probablement. Je recommande un usage exclusif (et correct) de fgets().

    Tout est expliqué ici :

    http://emmanuel-delahaye.developpez....tes.htm#saisie
    http://emmanuel-delahaye.developpez....s.htm#fichiers
    Pas de Wi-Fi à la maison : CPL

  17. #17
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 19
    Points : 5
    Points
    5
    Par défaut
    hum d'accord, mais en attendant je ne sais toujours pas pourquoi je ne peux pas envoyer ni recevoir de données !

    Bonsoir

Discussions similaires

  1. l'envoi des données à travers d'une socket
    Par rezguiinfo dans le forum Général Python
    Réponses: 5
    Dernier message: 22/01/2014, 16h18
  2. Réponses: 18
    Dernier message: 26/06/2008, 10h10
  3. Réponses: 1
    Dernier message: 05/04/2006, 09h49
  4. Modification des données impossible
    Par Virgile59 dans le forum Access
    Réponses: 8
    Dernier message: 03/03/2006, 14h41
  5. [socket] envoyer des données vers un port com
    Par Slimer dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 20/07/2004, 17h35

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