2009-11-21 7 views
0

J'ai un serveur proxy en cours d'exécution sur ma machine locale utilisée pour mettre en cache des images en surfant. J'ai configuré mon navigateur avec un proxy à 127.0.0.1, recevoir les requêtes HTTP, prendre les données et les renvoyer au navigateur. Cela fonctionne bien pour tout, sauf pour les grandes images. Quand je reçois les informations d'image, il affiche seulement la moitié de l'image (ex .: la moitié supérieure du logo google) Heres mon code:Réception d'une image via winsocket

char buffer[1024] = ""; 
    string ret(""); 
    while(true) 
    { 
     valeurRetour = recv(socketClient_, buffer, sizeof(buffer), 0); 
     if(valeurRetour <= 0) break; 
     string t; 
     t.assign(buffer,valeurRetour); 
     ret += t; 
     longueur += valeurRetour; 
    } 
    closesocket(socketClient_); 
    valeurRetour = send(socketServeur_, ret.c_str(),longueur, 0); 

le socketClient_ est non-blocage. Une idée de comment résoudre ce problème?

Répondre

2

Vous ne faites pas assez de distinction entre les valeurs de retour possibles de recv.

Il y a deux niveaux ici. Le premier est, vous êtes ensemble 0 et -1. 0 signifie que l'homologue distant a fermé sa moitié d'envoi de la connexion, de sorte que votre code fait la bonne chose ici, fermant son socket vers le bas, aussi. -1 signifie que quelque chose s'est produit en plus des données reçues. Il peut s'agir d'une erreur permanente, d'une erreur temporaire ou simplement d'une notification de la pile indiquant que quelque chose s'est produit en plus des données reçues. Votre code regroupe toutes ces possibilités et, en plus, les traite comme lorsque l'homologue distant ferme la connexion.

Le deuxième niveau est que toutes les raisons pour obtenir -1 de recv sont des "erreurs" dans le sens où le socket n'est plus utile. Je pense que si vous commencez à vérifier -1 et appelez WSAGetLastError pour savoir pourquoi vous avez -1, vous obtiendrez WSAEWOULDBLOCK, ce qui est normal puisque vous avez un socket non-bloquant. Cela signifie que l'appel recv ne peut pas renvoyer de données car il doit bloquer le thread d'exécution de votre programme pour le faire, et vous avez dit à Winsock que vous vouliez des appels non bloquants.

Une solution naïve est de ne pas sortir de la boucle sur WSAEWOULDBLOCK mais cela signifie simplement que vous brûlez le temps CPU en appelant recv encore et encore jusqu'à ce qu'il retourne des données. Cela va à l'encontre du principe des sockets non bloquantes, c'est-à-dire qu'ils permettent à votre programme de faire d'autres choses pendant que le réseau est occupé. Vous êtes censé utiliser des fonctions telles que select, WSAAsyncSelect ou WSAEventSelect pour être averti lorsqu'un appel de la fonction API est susceptible de réussir à nouveau. Jusque-là, vous ne l'appelez pas. Vous pouvez visiter The Winsock Programmer's FAQ. (Disclaimer: Je suis son mainteneur.)

0

Avez-vous analysé la transaction au niveau HTTP, c'est-à-dire les en-têtes vérifiés?

Comptez-vous des choses comme Chunked transferts?

Je n'ai pas de réponse définitive en partie à cause du manque de détails donnés ici.

Questions connexes