Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Problème de sortie de boucle (client pop)

13 réponses
Avatar
Bart
Bonjour, la question ne concerne que le C et non les sockets (sauf si
l'erreur viendrai de là...)
J'ai posé la même question sur developpez.com sans avoir de réponse
solutionnant ce code.

Ça fait un an que je n'ai plus rien codé, et aujourd'hui je m'y suis
remis et j'ai fait un petit client pop3 qui fonctionne pas trop mal.
Il se connecte, l'authentification est correcte, le stat est bon, les
messages peuvent être lues par un puts(bufferRead); bref ça va.
Seulement lire un message sur une console, surtout quand il est long, ce
n'est pas agréable, alors j'ai voulu sauvegarder les messages.
Voilà ma fonction pour recupérer les messages (toutes les autres sont
sur le même style) :

[CODE]int retr(char *bufferRead, char *bufferWrite, long nbRetr)
{

int err = 0;
memset(bufferRead, 0, sizeof bufferRead);
memset(bufferWrite, 0, sizeof bufferRead);

/* Envoie RETR au serveur */
sprintf(bufferWrite, "RETR %d\r\n", nbRetr);
printf("%s", bufferWrite);
err = send(sock, bufferWrite, strlen(bufferWrite), 0);
if (err == -1)
{
printf("Echec de l'envoi de \"%s\"\n",bufferWrite);
exit(EXIT_FAILURE);
}

/* Reception RETR */
err = recv(sock,bufferRead,PACKET, 0);
if (err == -1)
{
printf("Impossible de récuperer \"%s\"\n",bufferWrite);
exit(EXIT_FAILURE);
}
else
{
FILE *fp;
char nomFichier[255];
sprintf(nomFichier, "msg %d.txt", nbRetr);
if ((fp=fopen(nomFichier, "w+"))==NULL)
{
printf("Impossible d'enregistrer le mail.\n");
exit(EXIT_FAILURE);
}
/**************************************/
/* La j'essaye d'implémenter la sauvegarde du mail */
/**************************************/
}
}
[/CODE]

Alors ce que j'ai essayé (entre autre, parce que j'ai fait un peu tout
et n'importe quoi... surtout n'importe quoi puisque rien n'a
véritablement marché...)

fputs(bufferRead, fp). Donc déjà là, il y a un pb. Il enregistre le
message 1 sur plusieurs fichiers.

Je me suis dit, ça doit être à cause de la taille, et puis la fin de
message est caractérisée par un "\n.\n"
Alors j'ai fait une boucle infini, avec une recherche et comparaison
(strtok et strcmp donc) sur cette fin de message. Résultat boucle
inifini en effet... Après avoir enregistré correctement le message, le
dernier bloc de données se répete...
Après divers code que j'ai pris à droite, à gauche que je n'ai pas su
inserer correctement, j'ai mis celui d'Emmanuel Delahaye :

[CODE]
do
{
err = recv (sock, bufferRead, (int) sizeof bufferRead - 1, 0);

if (err != SOCKET_ERROR)
{
size_t nb_rec = (size_t) err;
bufferRead[nb_rec] = 0;
fprintf(fp, "%s", bufferRead);
if (strstr(bufferRead, "\n.\n") != NULL)
end = 1;


}
else
end = 1;
}
while (end != 1);
fclose(fp);
[/CODE]
Avec ça, j'ai le message qui est bien écrit dans le fichier, sans
"doublon", mais je ne sors pas de ma boucle.

Qu'est-ce que je fait de mal ?

Merci

3 réponses

1 2
Avatar
espie
In article <f4omve$1h5$,
Antoine Leca wrote:
Ca ne rend pas le code plus clair de definir une constante qui vaut
-1, justement parce que c'est une pratique non standard...


Ce n'est (peut-être) pas standard sous Unix, mais cela l'est sous Windows.
Et aussi dans un certain nombre de normes de programmation (la raison pour
laquelle c'est arrivé jusqu'à ce groupe).


recv() renvoie SOCKET_ERROR sous windows ?

Ou tu consideres comme `bonne pratique' de definir des constantes pour des
appels systeme evidents ?


Avatar
Antoine Leca
En news:f4oogn$2ab9$, Marc Espie écrivit:
In article <f4omve$1h5$,
Antoine Leca wrote:
Ca ne rend pas le code plus clair de definir une constante qui vaut
-1, justement parce que c'est une pratique non standard...


Ce n'est (peut-être) pas standard sous Unix, mais cela l'est sous
Windows. Et aussi dans un certain nombre de normes de programmation
(la raison pour laquelle c'est arrivé jusqu'à ce groupe).


recv() renvoie SOCKET_ERROR sous windows ?


Bah, il semble, oui.
http://www.sockets.com/winsock.htm#Recv
http://msdn2.microsoft.com/en-us/library/ms740121.aspx

En fait, Winsock établit l'usage d'utiliser SOCKET_ERROR plutôt que -1
(http://www.sockets.com/winsock.htm#Deviation_ReturnValues)


Ou tu consideres comme `bonne pratique' de definir des constantes
pour des appels systeme evidents ?


1º « Je » ne considère rien ; seulement, je sais qu'il y a des codes de
bonnes pratiques qui « imposent » ce genre de règles ; et tous ne sont pas
des pompes sans vergogne des documents MS sur le style.

2º Avec Windows, les appels système indiquent (en règle générale) un cas
d'erreur par la réponse 0 ou une autre réponse « dénuée de sens » (sauf COM
et dérivés, qui ont la logique inverse, tous les appels renvoient un SRESULT
et 0 veut dire... ERROR_SUCCESS).
Résultat de cette incohérence (qui vient de très très loin, genre DEC à tout
le moins), les recommendations de Microsoft et Win32 en particulier ont mis
l'accent sur l'utilisation de constantes indiquant des cas d'erreur,
INVALID_HANDLE_VALUE par exemple, pour attirer l'attention sur le traitement
des cas d'erreur et aussi cacher l'incohérence de l'API ; un programmeur
Windows est donc plutôt habitué à cette pratique, et sera nettement moins
choqué que tu ne peux l'être.
Ce n'est pas la peine de jeter la pierre à MS sur ce point, Unix n'est pas
franchement mieux où les appels systèmes (man 2) indique les cas d'erreur
par -1, et les appels de bibliothèques (man 3) par 0 ou NULL.

3º Sur l'intérêt ou pas d'être verbeux (genre C vs COBOL, match en N rounds,
P-ième reprise), je n'ai pas d'avis personnellement : j'interviens sur des
codes de tous les genres, et si j'ai quand même du mal au niveau d'APL ou à
l'opposé de COBOL, en dehors des extrêmes je m'adapte sans trop de mal ; et
même en C, on distingue facilement à l'½il un projet BSD d'un projet GNU sur
ce seul critère :-)


Antoine



Avatar
Bart
[snip]

Voilà, j'ai réussi à corriger mes problème grâce à vos conseils (et une
réécriture quasi from scratch).

Merci à vous tous.
1 2