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 :

Tester l'envoie en UDP


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 11
    Par défaut Tester l'envoie en UDP
    Bonjour à tous,
    Tout d'abord, je vais vous resituer un peu le contexte : j'ai écrit un programme en C++ à cross-compiler et à charger sur un micro-controleur. Ce programme permet de configurer les entrees/sorties du module en fonction de ce qui arrive sur un port UDP.

    Pour le tester, j'ai écrit ce petit programme, qui permet d'envoyer ce que je veux en UDP (pas forcement un string, mais pour l'intant j'essaye avec "Salut !") :
    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
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
     
    int main(void)
    {
    	uint16_t port = 8080;
    	uint32_t ip_destination;
    	char *string_ip = "127.0.0.1";
    	int sock;
    	int nb_octet;
    	const char *signal = "Salut !";
    	struct sockaddr_in info_socket;
     
    	/*Creation de la socket sur le domaine internet*/
    	sock = socket(PF_INET, SOCK_DGRAM, 0);
    	if (sock < 0)
      	{
    		perror("socket ");
    		exit(EXIT_FAILURE);
    	}
     
    	/*Initialisation de la structure contenant l'adresse de l'hote et le port utilise*/
    	info_socket.sin_family = AF_INET;
    	info_socket.sin_port = htons(port);	//conversion du numero de port
    	(void)inet_aton(string_ip, &ip_destination);	//conversion de l'adresse ip
    	info_socket.sin_addr.s_addr = ip_destination;
     
    	/*Liaison entre la socket et la structure*/
    	if ( bind(sock, (struct sockaddr *) &info_socket, sizeof (info_socket)) < 0)
    	{
    		perror("bind ");
    		exit(EXIT_FAILURE);
    	}
     
    	/*Envoie du signal*/
    	nb_octet = sendto(sock, signal, strlen(signal) + 1, 0, (struct sockaddr *) &info_socket, sizeof(info_socket));
     
    	if (nb_octet < 0)
    	{
    		perror ("sendto ");
    		exit (EXIT_FAILURE);
    	}
     
    	/*Fermeture de la socket*/
    	(void)shutdown(sock, 2);
    }
    Ma question est à propos du test de ce programme de test j'aimerais ne pas avoir à écrire un programme pour tester un programme de test, ça commancerait à être ridicule.

    J'ai donc essayé d'ecouter le port où le programme est sensé écrire : j'ai ouvert un terminal et lancé netcat comme ceci :
    Mais une fois Netcat lancé, lorsque j'exécute le programme, apparait l'erreur suivante :
    bind : Address already in use
    Est-ce que vous voyez pourquoi le binding ne se fait pas?
    Est-ce que vous connaissez autre chose que netcat pour tester un programme en UDP ?

    Merci d'avance.

  2. #2
    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 toma_n7 Voir le message
    Bonjour à tous,
    Tout d'abord, je vais vous resituer un peu le contexte : j'ai écrit un programme en C++ à cross-compiler et à charger sur un micro-controleur. Ce programme permet de configurer les entrees/sorties du module en fonction de ce qui arrive sur un port UDP.

    Pour le tester, j'ai écrit ce petit programme, qui permet d'envoyer ce que je veux en UDP (pas forcement un string, mais pour l'intant j'essaye avec "Salut !") :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	char *string_ip = "127.0.0.1";
     
    	/*Envoie du signal*/
    	nb_octet = sendto(sock, signal, strlen(signal) + 1, 0, (struct sockaddr *) &info_socket, sizeof(info_socket));
    Pourquoi +1 ? Tu as l'intention de transmettre le 0 ?

    L'histoire des chaines qui se terminent par un 0, c'est un principe du C. Qui te dit que cette notion a un sens quelconque sur la machine distante ? Et si elle est écrite en Pascal ?

    Il est donc d'usage de définir un format indépendant, comme par exemple :
    Libre au récepteur de placer un 0 à la place du LF ('\n' en C).

    D'autre part, ce programme semble être un client. A quel serveur est-il censé se connecter ? Tu as le code du serveur ?

    Il faut faire bien attention à ce qu'on fait avec les application UDP.

    Au fait, si il y a un bind(), c'est un serveur. Dans un client, pas de bind() !

    Ceci fonctionne :

    Client UDP :
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
     
    #if defined (WIN32)
    #include <winsock2.h>
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close (s)
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    #endif
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #if 0
    #define PORT 8080
    #else
    #define PORT 23
    #endif
     
    #if 0
    #define IP "127.0.0.1"
    #else
    #define IP "192.168.0.5"
    #endif
     
    int client (void)
    {
       /*Creation de la socket sur le domaine internet */
       SOCKET sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
       if (sock != INVALID_SOCKET)
       {
          struct sockaddr_in si_client = { 0 };
     
          /*Initialisation de la structure contenant l'adresse de l'hote et le port utilise */
          si_client.sin_family = AF_INET;
          si_client.sin_port = htons (PORT); //conversion du numero de port
          //conversion de l'adresse ip
          si_client.sin_addr.s_addr = inet_addr (IP);
     
          printf ("bound to %s:%d\n", IP, PORT);
     
          {
             /*Envoi du message */
             const char *message = "Salut !";
             int nb_octet = sendto (sock, message, strlen (message) + 1, 0,
                                    (struct sockaddr *) &si_client,
                                    sizeof (si_client));
     
             if (nb_octet > 0)
             {
                printf ("%d octets sent\n", nb_octet);
     
                {
                   char data[128];
                   int size_info_socket = sizeof (si_client);
                   int nb_octet = recvfrom (sock, data, sizeof data - 1, 0,
                                            (struct sockaddr *) &si_client,
                                            &size_info_socket);
     
                   if (nb_octet > 0)
                   {
                      printf ("%d octets received\n", nb_octet);
                      data[nb_octet] = 0;
                      printf ("< '%s'\n", data);
                   }
                   else if (nb_octet < 0)
                   {
                      printf ("recvfrom() : erreur locale\n");
                   }
                   else
                   {
                      printf ("recvfrom() : erreur distante\n");
                   }
                }
             }
             else if (nb_octet < 0)
             {
                printf ("sendto() : erreur locale\n");
             }
             else
             {
                printf ("sendto() : erreur distante\n");
             }
          }
          /*Fermeture de la socket */
          (void) shutdown (sock, 2);
       }
       else
       {
          printf ("socket() error\n");
       }
     
       return 0;
    }
     
    int main (void)
    {
    #if defined (WIN32)
       WSADATA WSAData;
       int erreur = WSAStartup (MAKEWORD (2, 0), &WSAData);
    #else
       int erreur = 0;
    #endif
       client ();
    #if defined (WIN32)
       WSACleanup ();
    #endif
       system ("pause");
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    bound to 192.168.0.5:23
    8 octets sent
    8 octets received
    < 'Salut !'
    Appuyez sur une touche pour continuer...
    Serveur
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
     
    #if defined (WIN32)
    #include <winsock2.h>
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close (s)
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    #endif
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #if 0
    #define PORT 8080
    #else
    #define PORT 23
    #endif
     
    int server (void)
    {
       /*Creation de la socket sur le domaine internet */
       SOCKET sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
       if (sock != INVALID_SOCKET)
       {
          struct sockaddr_in si_server = { 0 };
     
          /*Initialisation de la structure contenant l'adresse de l'hote et le port utilise */
          si_server.sin_family = AF_INET;
          si_server.sin_port = htons (PORT); //conversion du numero de port
          //conversion de l'adresse ip
          si_server.sin_addr.s_addr = htonl(INADDR_ANY); /* server */
     
          /*Liaison entre la socket et la structure */
          if (bind (sock, (struct sockaddr *) &si_server, sizeof si_server)
              != SOCKET_ERROR)
          {
     
             int fin = 0;
     
             while (!fin)
             {
                printf ("waiting for a client datagram\n");
     
                {
                   struct sockaddr_in si_client = { 0 };
                   /* reception  */
                   char data[128];
                   int size_si_client = sizeof (si_client);
                   int nb_octet = recvfrom (sock, data, sizeof data, 0,
                                            (struct sockaddr *) &si_client,
                                            &size_si_client);
                   if (nb_octet > 0)
                   {
                      if (!fin)
                      {
                         printf ("%d octets received\n", nb_octet);
                         /* echo */
                         nb_octet =
                            sendto (sock, data, nb_octet, 0,
                                    (struct sockaddr *) &si_client,
                                    sizeof (si_client));
     
                         if (nb_octet > 0)
                         {
                            printf ("%d octets sent\n", nb_octet);
                         }
                         else if (nb_octet < 0)
                         {
                            printf ("sendto() : erreur locale\n");
                            fin = 1;
                         }
                         else
                         {
                            printf ("sendto() : erreur distante\n");
                            fin = 1;
                         }
                      }
                   }
                   else if (nb_octet < 0)
                   {
                      printf ("recvfrom() : erreur locale\n");
                      fin = 1;
                   }
                   else
                   {
                      printf ("recvfrom() : erreur distante\n");
                      fin = 1;
                   }
                }
             }
          }
          else
          {
             printf ("bind() error\n");
          }
          /*Fermeture de la socket */
          closesocket (sock);
       }
       else
       {
          printf ("socket() error\n");
       }
     
       return 0;
    }
     
    int main (void)
    {
    #if defined (WIN32)
       WSADATA WSAData;
       int erreur = WSAStartup (MAKEWORD (2, 0), &WSAData);
    #else
       int erreur = 0;
    #endif
       server ();
    #if defined (WIN32)
       WSACleanup ();
    #endif
     
    #ifdef DEVCPP
       system ("pause");
    #endif
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    waiting for a client datagram
    8 octets received
    8 octets sent
    waiting for a client datagram

  3. #3
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 11
    Par défaut
    Merci pour la réponse !

    Le problème venait bien du bind, je pensais qu'il était nécessaire pour relier la socket à la structure. Je l'ai supprimé du code, et cela fonctionne comme je voulais : netcat reçoit bien le string que je lui envoie, sans le zéro.

    le sujet est donc

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Tester l'envoi d'email en local
    Par developeuz93 dans le forum ASP
    Réponses: 7
    Dernier message: 19/12/2008, 10h32
  2. Serialisation d'objet pour envoie par UDP
    Par olator dans le forum MFC
    Réponses: 3
    Dernier message: 07/11/2008, 19h11
  3. Tester l'envoi de mail en dev
    Par penguin50 dans le forum Ruby on Rails
    Réponses: 2
    Dernier message: 27/08/2008, 19h32
  4. [EasyPHP] Tester l'envoi d'e-mails sur son PC avec EasyPHP
    Par khalid_kha dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 8
    Dernier message: 03/08/2007, 17h36
  5. Problème envoi paquets udp
    Par oligig dans le forum Réseau
    Réponses: 6
    Dernier message: 13/10/2006, 15h11

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