Forum Programmation.c Probleme de communication UDP

Posté par  .
Étiquettes : aucune
0
27
sept.
2006
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:
[cpp]
/* Socket creation
* IP protocol family(PF_INET)
* UDP (SOCK_DGRAM)
*/
if( (socket_id = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 ) {
printf("! Error while creating socket !\n");
exit(1);
}

memset((char*) &server, sizeof(server), 0 );
server.sin_family = AF_INET; /* Used protocol: INET */
server.sin_addr.s_addr = INADDR_ANY; /* Any address can connect to the socket */
server.sin_port = htons(1234); /* setup the probing port*/



/* Connect to the socket */
if ( (i = bind(socket_id, (struct sockaddr *)&server, sizeof(server))) < 0 ) {
perror ("! Error while binding to socket !");
exit(3);
}

while(1)
{
/* wait client connection */
client_ln = sizeof(client);
n_read = recvfrom( socket_id, buf, MAX_BUF, 0, (struct sockaddr *)&client, &client_ln);

//pthread_mutex_lock (&mutex);

got = n_read;

if((n_read < 0) ) {
printf("! Error while receiving data (n_read = %d from %s:%d) !\r", n_read, inet_ntoa(client.sin_addr), ntohs(client.sin_port));
rerrors++;
if (n_read < 0)
exit(4);
}
else
{

received += n_read;
for(i=0;i<MAX_BUF;i++)
{
if (buf[i]!=(i%255))
{
rerrors++;
printf("@%d => receieved: %d expected: %d \n", i, buf[i], i%255);
}
}
}


/* Now, send the answer */
n_sent = sendto( socket_id, buf, MAX_BUF, 0, (struct sockaddr *)&client, sizeof(client));

if(n_sent < 0 )
{
printf("! Error while answering to %s", get_ip(client.sin_addr.s_addr));
serrors++;
if (n_sent < 0)
exit(5);
}
else
{
sent += n_sent;
}

//pthread_mutex_unlock (&mutex);
}
[/cpp]

Client:
[cpp]
struct sockaddr_in server;
struct hostent *host;
unsigned char buf[MAX_BUF];
int buf_len, socket_id, n_sent, n_read, i;
u_long address;
u_long nb_send=0, nb_read=0;

//if (argc != 2)
{
printf("> Usage: %s <server name> <udp port>\n",argv[0]);
}

/* Socket Creation
* IP protocol family(PF_INET)
* UDP (SOCK_DGRAM)
*/
if( (socket_id = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 ) {
printf("! Error while creating UDP socket !\n");
exit(1);
}

/* No need to cal bind() because we are using UDP */
server.sin_family = AF_INET;
/* set the connection port */
server.sin_port = htons(1234);

if (argc > 1)
{
if ( (host = (struct hostent*) gethostbyname(argv[1])) == NULL ) {
printf("! Unkown host name !\n");
exit(2);
}
else
{
/* Get host IP address */
//address = *((u_long*)host->h_addr_list[0]);
address = inet_addr("127.0.0.1");
server.sin_addr.s_addr = address;

}
}
else
{
printf("] No host specified, using localhost then...\n");
server.sin_addr.s_addr = inet_addr("192.168.1.250");
}



do
{
/* On compose le message */
for(i=0;i<MAX_BUF;i++)
buf[i]= (i % 255);
buf_len = MAX_BUF; // remove the return char

/* Message sent to the remote server */
n_sent = sendto( socket_id, buf, buf_len, 0, (struct sockaddr *)&server, sizeof(server));

if( n_sent < 0 )
{
printf("! Error while sending the message !\n");
exit(3);
}
else
{
nb_send+=n_sent;
}



/* buffer cleanning */
//memset( buf, 0, MAX_BUF);

/* wait for the server response */
n_read = recvfrom(socket_id, buf, MAX_BUF, 0, NULL, NULL);

if( n_read < 0 || n_read < 1000)
{
printf("! Error while retreiving the answer !\n");
//exit(4);
}
else
{
nb_read += n_read;
}

if ( (nb_send%(1024*1024/MAX_BUF)) == 0 )
{
printf("] Sent %d Mo [%d]", nb_send/(1024*1024), n_sent);
printf("- Received %d Mo [%d] \r", nb_read/(1024*1024), n_read);
fflush(stdout);
}



} while (1);
[/cpp]

Si quelqu'un peut m'expliquer :jap:
  • # Outils de debug réseau

    Posté par  . Évalué à 4.

    A la lecture du code je ne vois rien de choquant...
    Par contre pour voir ce qui passe par le réseau, je te conseille de lancer un ethereal (qui s'appelle wireshark dans ses dernières versions) pour capturer le trafic, ce qui te permettra de voir quelle tête ont vraiment les paquets de 64k. (Attention, comme ethernet a une taille max de paquet d'environ 1500 octets, tu vas te retrouver avec de la fragmentation IP donc plusieurs morceaux pour un paquet UDP, à l'affichage)
    Tu peux aussi simuler des clients/serveurs avec l'outil "netcat" ou "nc" (il a plusieurs noms...) qui permet de recevoir ou d'émettre des paquets, en TCP comme en UDP.
    par exemple "nc -l -p 1234 -u -o dump.txt" pour etre en écoute sur le port 1234 en udp, et faire un dump hexa de ce qui est reçu dans un fichier

    "nc -u host 1234" pour emettre vers ce port (l'équivalent UDP d'un telnet)
    Je ne crois pas qu'on puisse maitrise la taille des paquets UDP émis.
    • [^] # Re: Outils de debug réseau

      Posté par  . Évalué à 1.

      J'ai trouvé: visiblement il ne me digerait pas MAX_BUF comme 65000 mais comme 1000 alors que j'ai bien un #define MAX_BUF 65000 :o
      Etrange mais bon, ca marche maintenant !
      Merci :)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.