[C/Linux] Probleme de communication UDP

Probleme de communication UDP [C/Linux] - C - Programmation

Marsh Posté le 27-09-2006 à 09:54:23    

Salut !
 
 
J'ai un soucis: J'utilise une red hat enterprise 4 et j'essaye de faire un server/client udp.
Or lorsque j'envoie un tableau de 64Ko, seul 1000 octets sont envoyé (sendto retourne 1000). Si je compile le meme soft sous cygwin, et bien ca envoie bien 64Ko. Derniere étape: client sous cygwin et serveur sous linux => le client cygwin envoie bien 64Ko mais le serveur sous linux recoit 1000 octets (recvfrom retourne 1000).
 
Je ne comprends pas trop...
 
Voici mon code:
 
Serveur:

Code :
  1. /* Socket creation
  2.     * IP protocol family(PF_INET)
  3.     * UDP (SOCK_DGRAM)
  4.     */
  5.     if( (socket_id = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 ) {
  6.         printf("! Error while creating socket !\n" );
  7.         exit(1);
  8.     }
  9.     memset((char*) &server, sizeof(server), 0 );
  10.     server.sin_family = AF_INET;                        /* Used protocol: INET */
  11.     server.sin_addr.s_addr = INADDR_ANY;                /* Any address can connect to the socket */
  12.     server.sin_port = htons(1234);                      /* setup the probing port*/
  13.     /* Connect to the socket */
  14.     if ( (i = bind(socket_id, (struct sockaddr *)&server, sizeof(server))) < 0 ) {
  15.         perror ("! Error while binding to socket !" );
  16.         exit(3);
  17.     }
  18.     while(1)
  19.     {
  20.         /* wait client connection */
  21.         client_ln = sizeof(client);
  22.         n_read = recvfrom( socket_id, buf, MAX_BUF, 0, (struct sockaddr *)&client, &client_ln);
  23.         //pthread_mutex_lock (&mutex);
  24.     got = n_read;
  25.         if((n_read < 0) ) {
  26.             printf("! Error while receiving data (n_read = %d from %s:%d) !\r", n_read, inet_ntoa(client.sin_addr), ntohs(client.sin_port));
  27.             rerrors++;
  28.             if (n_read < 0)
  29.  exit(4);
  30.         }
  31.         else
  32.         {
  33.    
  34.         received += n_read;
  35.             for(i=0;i<MAX_BUF;i++)
  36.             {
  37.              if (buf[i]!=(i%255))
  38.              {
  39.                 rerrors++;
  40.                 printf("@%d => receieved: %d expected: %d \n", i, buf[i], i%255);
  41.              }
  42.            }
  43.         }
  44.         /* Now, send the answer */
  45.         n_sent = sendto( socket_id, buf, MAX_BUF, 0, (struct sockaddr *)&client, sizeof(client));
  46.         if(n_sent < 0 )
  47.         {
  48.                 printf("! Error while answering to %s", get_ip(client.sin_addr.s_addr));
  49.                 serrors++;
  50.                 if (n_sent < 0)
  51.   exit(5);
  52.         }
  53.         else
  54.         {
  55.             sent += n_sent;
  56.         }
  57.         //pthread_mutex_unlock (&mutex);
  58.   }


 
Client:

Code :
  1. struct sockaddr_in server;
  2.     struct hostent *host;
  3.     unsigned char buf[MAX_BUF];
  4.     int buf_len, socket_id, n_sent, n_read, i;
  5.     u_long address;
  6.     u_long nb_send=0, nb_read=0;
  7.     //if (argc != 2)
  8.     {
  9.         printf("> Usage: %s <server name> <udp port>\n",argv[0]);
  10.     }
  11.    /* Socket Creation
  12.     * IP protocol family(PF_INET)
  13.     * UDP (SOCK_DGRAM)
  14.     */
  15.      if( (socket_id = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 ) {
  16.         printf("! Error while creating UDP socket !\n" );
  17.         exit(1);
  18.     }
  19.     /* No need to cal bind() because we are using UDP */
  20.     server.sin_family = AF_INET;
  21.     /* set the connection port */
  22.     server.sin_port = htons(1234);
  23.    
  24.     if (argc > 1)
  25.     {
  26.         if ( (host = (struct hostent*) gethostbyname(argv[1])) == NULL ) {
  27.             printf("! Unkown host name !\n" );
  28.             exit(2);
  29.         }
  30.         else
  31.         {
  32.             /* Get host IP address */
  33.             //address = *((u_long*)host->h_addr_list[0]);
  34.             address = inet_addr("127.0.0.1" );
  35.             server.sin_addr.s_addr = address;
  36.            
  37.         }
  38.     }
  39.     else
  40.     {
  41.         printf("] No host specified, using localhost then...\n" );
  42.         server.sin_addr.s_addr = inet_addr("192.168.1.250" );
  43.     }
  44.     do
  45.     {
  46.         /* On compose le message */
  47.         for(i=0;i<MAX_BUF;i++)
  48.          buf[i]= (i % 255);
  49.         buf_len = MAX_BUF; // remove the return char
  50.         /* Message sent to the remote server */
  51.         n_sent = sendto( socket_id, buf, buf_len, 0, (struct sockaddr *)&server, sizeof(server));
  52.         if( n_sent < 0 )
  53.         {
  54.             printf("! Error while sending the message !\n" );
  55.             exit(3);
  56.         }
  57.         else
  58.         {
  59.             nb_send+=n_sent;
  60.         }
  61.         /* buffer cleanning */
  62.         //memset( buf, 0, MAX_BUF);
  63.         /* wait for the server response */
  64.         n_read = recvfrom(socket_id, buf, MAX_BUF, 0, NULL, NULL);
  65.         if( n_read < 0 || n_read < 1000)
  66.         {
  67.             printf("! Error while retreiving the answer !\n" );
  68.             //exit(4);
  69.         }
  70.         else
  71.         {
  72.             nb_read += n_read;
  73.         }
  74.         if ( (nb_send%(1024*1024/MAX_BUF)) == 0 )
  75.         {
  76.             printf("] Sent %d Mo [%d]", nb_send/(1024*1024), n_sent);
  77.      printf("- Received %d Mo [%d] \r", nb_read/(1024*1024), n_read);
  78.      fflush(stdout);
  79.  }
  80.        
  81.     } while (1);


 
Si quelqu'un peut m'expliquer :jap:

Reply

Marsh Posté le 27-09-2006 à 09:54:23   

Reply

Marsh Posté le 27-09-2006 à 10:23:50    

farok a écrit :

J'ai un soucis: J'utilise une red hat enterprise 4 et j'essaye de faire un server/client udp.
Or lorsque j'envoie un tableau de 64Ko, seul 1000 octets sont envoyé (sendto retourne 1000).  


Ben oui, c'est à toi de gérer le découpage du bloc. C'est à ça que sert le code retour de sendto()...
 
Idem en réception, il faudra réassembler le bloc. J'espère que tu as prévu de transmettre la taille ou un délimiteur...

Message cité 1 fois
Message édité par Emmanuel Delahaye le 27-09-2006 à 10:25:13

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-09-2006 à 10:39:34    

Emmanuel Delahaye a écrit :

Ben oui, c'est à toi de gérer le découpage du bloc. C'est à ça que sert le code retour de sendto()...
 
Idem en réception, il faudra réassembler le bloc. J'espère que tu as prévu de transmettre la taille ou un délimiteur...


 
Arf zut !
Je pensais que l'on etait limité par la taille d'une trame (64Ko) pas par le systeme !
 
Il n'y a pas moyen de modifier un paramètre quelque part (systeme ou via une fonction ?)
 

Reply

Marsh Posté le 27-09-2006 à 10:50:08    

farok a écrit :

Il n'y a pas moyen de modifier un paramètre quelque part (systeme ou via une fonction ?)


Mauvais reflexe. Le code doit être indépendant du système...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-09-2006 à 10:59:43    

farok a écrit :

Arf zut !
Je pensais que l'on etait limité par la taille d'une trame (64Ko) pas par le systeme !


et bien si justement c'est 65.527o la taille maximale de la charge utile d'un paquet UDP. S'il la taille de ton paquet UDP dépasse la MTU, alors il y a de la fragmentation IP.
 
Maintenant si tu dis que sur le linux tu ne reçois que 1000o dans l'application, c'est un problème applicatif. Tu devrais regarde les retour de sendto et bien vérifier tout ça.

Reply

Marsh Posté le 27-09-2006 à 11:01:48    

pour le sendto je veux dire qu'étant donné UDP, si sendto n'a pas envoyé exactement le nombre d'octets demandé, alors il y a un problème. On n'est pas en TCP.

Reply

Marsh Posté le 27-09-2006 à 12:23:38    

Alors je pense avoir (à moitié) élucidé mon soucis
J'ai defini un define MAX_BUF dans mon application qui etait mise à 65000
hors à l'execution, si je faisais un printf("%d\n",MAX_BUF);
ca me sortais des lignes de 1000 :o
 
le define était dans un .h externe mais en le changeant par BIG_BUFFER, ca roule maintenant !
 
Je n'avais aucun warning avec gcc 346 :??:

Reply

Marsh Posté le 27-09-2006 à 13:46:18    

farok a écrit :

Alors je pense avoir (à moitié) élucidé mon soucis
J'ai defini un define MAX_BUF dans mon application qui etait mise à 65000
hors à l'execution, si je faisais un printf("%d\n",MAX_BUF);
ca me sortais des lignes de 1000 :o
 
le define était dans un .h externe mais en le changeant par BIG_BUFFER, ca roule maintenant !
 
Je n'avais aucun warning avec gcc 346 :??:


Je suis très étonné qu'il faille bricoler comme ça dans les headers... En principe, sauf indication contraire très explicite, on a pas le doit de modifier les headers.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-09-2006 à 15:40:46    

humm je parlais d'un header a moi, donc pas de soucis ;)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed