ssmint
Messages postés43Date d'inscriptionmercredi 30 novembre 2005StatutMembreDernière intervention 5 décembre 2008
-
25 nov. 2007 à 06:17
nickydaquick
Messages postés416Date d'inscriptionvendredi 31 janvier 2003StatutMembreDernière intervention19 décembre 2013
-
4 déc. 2007 à 00:50
Bonsoir à tous,
une fois de plus mon insomnie me pousse vers mon IDE pour une session de codage.. (Ou pour le coup c'est le code qui me rend insomniaque!)
Bref! Cette nuit il s'agit de problèmes de sockets, plus précisément winsock et l'envoie de fichier.
Jusqu'à maintenant pour envoyer un fichier, je me contentais de le bufferiser, puis de passer l'intégralité du buffer à la fonction send. A chaque fois c'était de petits fichiers (<100Ko). Mais cette fois je dois envoyer des fichiers allant de 200Ko à 100Mo. Mais bon je vais pas mettre 100Mo en RAM, jaimerais donc mettre la taille max du buffer d'envoie et de reception.
J'ai testé :
getsockopt(sock,SOL_SOCKET,SO_SNDBUF,(char*)&size, &s_int)
getsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char*)&size, &s_int)
A chaque fois j'obtiens 96 768. Pas trop cohérent vu que il m'arrive de passer un buffer entier de 200Ko à la fonction send et ça fonctionne, bizarre...
Mais bon passons.
Je fais donc une petite boucle qui s'occupe de fractionner mon fichier et de l'envoyer, côté reception(client) ça donne ça :
// size = taille du fichier que l'on reçoie
// packetsize = taille de la fraction de fichier envoyé en une fois (en général 200Ko)
// size%psize = // reste de la division pour avoir un dernier packet de la taille de la fraction de fichier restant.
// tot sert à savoir combien d'octect son reçu grâce au retour de recv()
....
Le tout fonction trés bien mais une fois sur 2 (surtout avec de gros fichiers) la variable tot est inférieur à size, par conséquent ( et j'ai vérifié) à certaines itérations de la boucle for, la fonction recv ne remplit le buffer que partiellement. Le WriteFile qui passe derriere recopie donc la fin du buffer de l'itération précédant. A la fin du traitement mon fichier est donc corrompu.
J'ai essayé ça avec des packetsize allant de 150 octect à 1,5Mo, toujours le même soucis, ça marche une fois de temps en temps.
J'aimerais donc savoir d'où vient le problème....
Autrement j'ai vu un flag intérressant sur MSDN pour la fonction recv :
MSG_WAITALL qui impose à la fonction d'attendre tant que le buffer n'est pas rempli mais quand je le met dans la fonction le compilo me dit que la constante n'existe pas!!!
Elle n'est pas dans winsock2.h..!
Voilà désolé pour la longeur du post..
Merci d'avance.
nickydaquick
Messages postés416Date d'inscriptionvendredi 31 janvier 2003StatutMembreDernière intervention19 décembre 20133 4 déc. 2007 à 00:50
Salut,
le probleme avec les sockets et ton programme en fait est que le changement de la taille du buffer n'a rien avoir . C'est l'algorithme qu'il faut un tout petit peu modifier. Lorsque tu dois envoyer 200Ko par une socket , meme si la taille du buffer est 8192(8Ko) le message est deja envoye par paquets de 8Ko. Alors en essayant d'en renvoyer par send un autre gros paquet tu risques de solliciter la socket avant qu'elle ne soit prete a envoyer d'autres donnees.
Alors je te conseille d'utiliser des sockets non-bloquantes avec un server Unithread, qui verifie l'etat de la socket grace a la fonction poll ou select , et les FD_SET.
Dans ce cas tu seras capable de verifier lorsque la socket sera prete a envoyer des donnees , lorsqu'elle en aura recu, s'il y a des erreurs relatives ... bref capable d'agir au bon moment.
J'espere avoir aider, salut
je suis heureux de faire partie d'une grande famille ...!