Pb de Broken Pipe en C (bsd) - Application FTP

Pb de Broken Pipe en C (bsd) - Application FTP - C - Programmation

Marsh Posté le 15-04-2004 à 16:37:08    

Bonjour a tous,
je viens vous importuner sur ce merveilleux forum pour soliciter votre aide afin de résoudre un problème dont je ne parviens pas a trouver la solution idéale.
 
Explication: je code un serveur ftp sous freebsd, et j'ai un léger soucis avec une de mes fonctions de transfert de fichier (fonction RETR). En effet je ne vous apprendrai rien en vous disant que lorsqu'un client se connecte a un serveur ftp et qu'il rapatrie le fichier, il a la possibilité d'annuler le transfert. Soit, voici une partie du code de ma fonction de transfert:
 

Code :
  1. while((c = getc(pf)), !feof(pf))
  2.             {
  3.               if(i < buf)
  4.                 {
  5.                   buffer[i] = c;
  6.                   i++;
  7.                 }
  8.               else
  9.                 {
  10.                   if(write(cdtp, buffer, i) < 0)
  11.                     return(0);
  12.                   buffer[0] = c;
  13.                   i = 1;
  14.                 }
  15.             }
  16.           if(write(cdtp, buffer, i) < 0)
  17.             return(0);
  18.           close(cdtp);
  19.           return(1);


 
J'attire votre attention sur les deux appels a write présent dans mon code. En effet si le client annule le transfert de fichier, il détruit la connexion établie pour le canal de transfert et par conséquent il rend obsolète le descripteur de fichier (socket) cdtp... et malheureusement moi, j'essaye d'écrire dedans. Du coups mon application se termine avec un broken pipe! Comme vous pouvez le constater j'ai tenter de recuperer une valeur d'erreur avec le test si write < 0 mais sans succès. Toutefois je sais qu'il est possible d'utiliser la fonction select() afin de savoir si le socket est toujours présent et si il est pret pour l'écriture ou la lecture. Voici ce que j'ai essayé:
 

Code :
  1. while((c = getc(pf)), !feof(pf))
  2.             {
  3.               if(i < buf)
  4.                 {
  5.                   buffer[i] = c;
  6.                   i++;
  7.                 }
  8.               else
  9.                 {
  10.                   FD_ZERO(&wfds);
  11.                   FD_SET(cdtp, &wfds);
  12.                   if((retval = select(cdtp+1, NULL, &wfds, NULL, &tv)) > 0)
  13.                     write(cdtp, buffer, i);
  14.                   else if(!retval)
  15.                     return(0);
  16.                   else
  17.                     return(-1);
  18.                   buffer[0] = c;
  19.                   i = 1;
  20.                 }
  21.             }


 
Mais malheureusement lorsque j'annule le transfert de fichier j'obtiens toujours un broken pipe :( Je n'arrive pas a comprendre pourquoi, pourriez vous m'aider ?  
 
En vous remerciant,
Kantorovich.


---------------
Ya pas que le riz et les pates dans la vie, ya le bleh aussi.
Reply

Marsh Posté le 15-04-2004 à 16:37:08   

Reply

Marsh Posté le 15-04-2004 à 16:52:47    

 while((c = getc(pf)), !feof(pf))  
 
 
boom. t'as rien compris à feof
 
 
int c;
 
while( (c=getc(pf)) != EOF) { /*  */ }

Reply

Marsh Posté le 15-04-2004 à 16:57:06    

lol, écoute premièrement ca n'a rien a voir avec le problème pour lequel j'ai posté et deuxièmement, ca fonctionne tout à fait de la manière dont je l'utilisais (j'aurai eu le temps de m'en appercevoir je crois sinon :) )


---------------
Ya pas que le riz et les pates dans la vie, ya le bleh aussi.
Reply

Marsh Posté le 15-04-2004 à 17:01:14    

à ben si ça a avoir. avec ton feof tu incapable de détecter quoi que ce soit. cette méthode est mauvaise car elle ne permet pas de détecter les erreurs d'E/S

Reply

Marsh Posté le 15-04-2004 à 17:19:35    

J'ai fais ta modification, mais ca n'a pas changé le problème d'écriture sur le socket lors d'un ABOR... je dois surement mal utiliser le select, et c'est précisement la dessus que je solicite votre aide.


---------------
Ya pas que le riz et les pates dans la vie, ya le bleh aussi.
Reply

Marsh Posté le 15-04-2004 à 23:21:25    

Personne n'a une petite idée pour mon problème ? :'(


---------------
Ya pas que le riz et les pates dans la vie, ya le bleh aussi.
Reply

Marsh Posté le 16-04-2004 à 08:57:30    

je ne comprens pas pourquoi tu utilises la méthode 'write' et non pas la méthode 'send', qui me parait plus appropriée.
 
man 2 send:

Code :
  1. NOM
  2.        send, sendto, sendmsg - Envoyer un message sur une socket.
  3. SYNOPSIS
  4.        #include <sys/types.h>
  5.        #include <sys/socket.h>
  6.        int send(int s, const void *msg, size_t len, int flags);
  7. ...
  8. Le paramètre flags peut contenir une ou plusieurs des options suivantes
  9. ...
  10.        MSG_NOSIGNAL
  11.               demande  de ne pas envoyer de signal SIGPIPE d'erreur sur les sockets connectées lorsque le correspondant coupe la connexion.  L'erreur  EPIPE  est toutefois renvoyée.


 
je n'ai donc pas testé, mais soit tu utilises la fonction 'send', soit tu interceptes le signal SIGPIPE qui est envoyé à l'application, et qui provoque une erreur de type 'broken pipe' si aucun handler n'est déclaré.


Message édité par SoWhatIn22 le 16-04-2004 à 08:58:36
Reply

Marsh Posté le 16-04-2004 à 17:24:01    

En faite j'utilisais read et write car la fonction read permet de renvoyer 0 lorsqu'elle recoit un eof contrairement a recv. Mais merci pour l'info a propos du flag de send, je l'ignorai.
Pourrais tu dailleurs me dire comment/ou je pourrai me procurer les pages du man en francais?
 
merci.


---------------
Ya pas que le riz et les pates dans la vie, ya le bleh aussi.
Reply

Marsh Posté le 16-04-2004 à 18:56:53    

Reply

Sujets relatifs:

Leave a Replay

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