Pb socket

fcbouan Messages postés 10 Date d'inscription lundi 2 août 2004 Statut Membre Dernière intervention 21 décembre 2004 - 30 août 2004 à 12:17
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 - 31 août 2004 à 14:10
bonjour,

mon prog dialogue via socket avec un serveur ftp. J envoie mes commande et recois la reponse serveur de facon synchrone dans un buffer, mais de temps a autre la reponse serveur est incomplete et donc ma commande suivante fais une seg fault.
Que j utilise read ou recv c pareil :

cas 1 normal :
USER ...
331 Password required ...
PASS ....
230-User ... logged in.
..., account expires ........
230 User '....' allowed by access rules
PASV
....

cas 2 lecture incomplete :
USER ...
331 Pasword required ...
PASS ....
230-User ... logged in.
PASV
seg fault

le code :

int FTPSendCommand(const int fsock, const char * Cmd, const char * fLogName)
{
static char BuffCmd[BUFFER_SIZE];
int error=0;

sprintf(BuffCmd,"%s\n",Cmd);
write(fsock,BuffCmd,strlen(BuffCmd));
FTPLog(BuffCmd,fLogName);
printf(BuffCmd);

bzero(BuffCmd, BUFFER_SIZE);
read(fsock,BuffCmd,BUFFER_SIZE);
//recv(fsock,BuffCmd,BUFFER_SIZE,0)
FTPLog(BuffCmd,fLogName);
printf(BuffCmd);

return FTPExtractReplyCode(BuffCmd);
}

quelqu' un a une idée ?

7 réponses

cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
30 août 2004 à 14:34
si ce que tu recois ne se termine pas par un '\n' (par exemple), tu refais un recv, jusqu'a ce que celui ci en contienne un. la tu concatenes la bonne partie de ce recv a celui d'avant. et a ce moment la seulement tu essaies d'extraire le code de reply !

en gros t'as besoin : d'un tableau de char qui va recevoir le read ou recv, d'un autre tableau qui va contenir la véritable commande.
tu fais une boucle avec un read ou un recv, tu regardes si ce que t'as recu contient un \n, sinon tu places tout dans l'autre tableau de char. si il y en a un, tu ne places que la partie avant le \n a la fin de ton autre tableau de char.

et voila, si ca a pu t'eclairer...
a+ ;)
0
fcbouan Messages postés 10 Date d'inscription lundi 2 août 2004 Statut Membre Dernière intervention 21 décembre 2004
30 août 2004 à 15:04
merci , j' y ai pensé mais le pb c'est que le recv ou read lit toute la reponse a ma commande passé en write ( meme si le buffer contient une partie incomplete) et donc le recv ou read suivant reste en attente puisque la reponse a deja été lu :[
0
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
30 août 2004 à 17:16
je comprends pas trop : 'le recv ou read lit toute la reponse a ma commande passé en write ( meme si le buffer contient une partie incomplete) '.
en gros tu dis qu'une partie de ce qui est recu est perdu definitivement? c'est pas possible ou alors j'ai pas pigé ce que tu dis.
imaginons que le server veuille t'envoyer la chaine "salut\n".
2 possibilités :
ou bien un seul recv recoit la totalité de la chaine salut, ce que tu vois en verifiant qu'effectivement a la fin de ce que tu as recu il y a un '\n'
ou alors le premier recv ne te permet de recevoir que mettons "sal". tu detectes que la chaine recue n'est pas complete puisque ce que tu as recu se termine par 'l' et non pas par '\n' (tu sais la fin de ce que tu as recu, car tu connais le nmbre d'octets recu qui est le resultats de recv. si recv renvoie 5, les octets pertinents de ton buffer vont de buffer[0] a buffer[4])
dans ce cas, tu fais un autre recv ! comme le server a voulu envoyé "salut\n", tu peux etre sur que le 2eme ne va pas bloquer indefiniment, car il va bientot recevoir "ut\n".

bon voila... il est possible que j'ai mal compris, mais en tout cas, il y a forcement une solution a ton probleme...

un truc important : si tu veux traiter ensuite une chaine recue par socket par une fonction annexe (comme ta fonction FTPExtractReplyCode), il vaut mieux que le tableau de char que tu lui passes en parametre se termine par un '\0' (ce qui lui permet de connaitre la fin de ce qu'elle doit traiter, (ou alors tu lui passes en 2eme argument le nombre d'octets de la chaine qu'elle doit traiter)).
si tu fais recv(fsock, buffer, SIZE_BUFFER,0), un 0 n'est pas placé a la fin de ce qui a été placé dans buffer !
tu dois le faire toi meme en faisant ca:
int r = recv(fsock, buffer, SIZE_BUFFER-1,0);
if (r != SOCKET_ERROR)
buffer[r] = 0; // sans pb de debordement, car r <= SIZE_BUFFER-1

a+ ;)
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
30 août 2004 à 18:19
Salut,
Je crois effectivement que le probleme vient du zéro final du buffer qu'il faut rajouter manuellement.
En plus on a pas eu le code de la fonction FTPExtractReplyCode() et pourtant c'est elle qui a l'air de planter.

Sinon a propos du "salut\n" envoyé en 2 fois.. perso j'y crois pas, le protocole TCP serait plutot du genre a coller plusieurs petits messages ensembles, mais pas a les découper par morceaux de 3 octets.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
30 août 2004 à 19:16
'mais de temps a autre la reponse serveur est incomplete' <- c'est de la que j'ai tiré ce que j'ai dit.
avec une connection lente, il est de toute maniere pas du tout improbable (meme avec une connection haut débit de toutes manieres, il suffit que la bande passante du serveur commence a etre saturée) que des messages du serveur arrivent fragmentés.

en+ je crois savoir (a verifier ;) que des packets tcp peuvent etre fragmentés 'en route' (ie il est possible que certains routeurs surchargés ne puissent pas transmettre un paquet entier d'un seul coup; d'ou un leger delai entre deux envois et une fragmentation)

en tout cas j'ai déja vérifié la fragmentation, bon avec des paquets plus gros que ceux de la taille d'un "salut"; mais en tout cas ca existe. TCP regroupe quand il peut...

a+ ;)
0
fcbouan Messages postés 10 Date d'inscription lundi 2 août 2004 Statut Membre Dernière intervention 21 décembre 2004
31 août 2004 à 11:10
le serveur envoie apres le USER et PASS un certain nombre d' information ( code 230 ftp) en plusieur lignes (donc separe par des /n) .
J'ai l impression le recv s arrete de temps en temps au premier /n mais c 'est aléatoire et ca je comprend pas :/

Comment je peu savoir qu' il reste du texte reponse de mon serveur ou non à recevoir, sachant que s il en reste pas le recv reste en attente d'un chose qui n arrivera pas et donc bloquera la suite du prog ( en ftp etant obligé d agir de maniere synchrone commande-reponse) ?
0
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
31 août 2004 à 14:10
tu peux toujours mettre un timeout sur le recv, (il faut le faire en faisant un select(0,&set,0,0,&timeout); ou set est un ensemble de sockets (type FD_SET), timeout une variable de type timeval, recherche sur le site ou google pr plus d'infos sur ca)
sinon crée un thread qui ne fait que des recv, comme ca ca ne bloque pas le reste de ton programme...
tu peux aussi revoir ta fonction extract machin, débrouille toi pr qu'elle ne plante pas qd ya une information de moins (qui de toutes manieres ne doit pas etre essentielle sinon elle serait envoyée)

a+ ;)
0
Rejoignez-nous