2010-04-21 8 views
2

J'ai eu une autre question à propos de ce problème, mais je n'ai pas demandé correctement, alors là je vais encore! J'envoie un fichier en l'envoyant par morceaux. En ce moment, je joue avec des nombres différents pour la taille de ce morceau, pour voir quelle taille est la plus efficace.Bizarre problème send() (avec le journal Wireshark)

Lors du test sur localhost, toute taille de bloc semble fonctionner correctement. Mais quand je l'ai testé sur le réseau, il semble que la taille maximale des segments soit de 8191 octets. Si j'essaie quelque chose de plus élevé, le transfert devient extrêmement, péniblement, lentement. Pour voir ce qui se passe, voici les 100 premières lignes de journaux Wireshark lorsque j'utilise une taille de bloc de 8191 octets, et quand j'utilise une taille de bloc de 8192 octets: (l'expéditeur est 192.168.0.102, et le récepteur est 192.168.0.100)

8191: http://pastebin.com/E7jFFY4p

8192: http://pastebin.com/9P2rYa1p

Remarquez comment dans le journal 8192, sur la ligne 33, le récepteur prend beaucoup de temps pour ACK les données. Cela se produit de nouveau à la ligne 103 et à la ligne 132. Je crois que ce retard est la racine du problème.

Notez que je n'ai pas modifié l'option SO_SNDBUF ni l'option TCP_NODELAY. Pourquoi ma demande est-elle, pourquoi est-ce que je reçois des accusés de réception différés lors de l'envoi de fichiers en blocs de 8192 octets, alors que tout fonctionne correctement avec des blocs de 8191 octets?

+0

Pourriez-vous montrer un code? Cela pourrait nous donner une meilleure idée de ce qui se passe. De plus, votre code fonctionne-t-il des deux côtés? ou juste 1 côté de la connexion? – Pretzel

+0

J'ai ajouté un pseudo-code des sections pertinentes. – Meta

Répondre

1

Je l'ai compris! Tout d'abord par moi-même, puis après un peu plus creuser, je trouve ceci: http://support.microsoft.com/kb/823764

Qu'est-ce qui se passait réellement est que parce que le tampon d'émission alloués par Winsock est par défaut (sur ma machine) exactement 8192 octets, quand je mets que quantité d'octets dans le tampon (le remplir complètement), le prochain send() donnera WSAEWOULDBLOCK. Ensuite, je ne recevrais que le prochain FD_WRITE une fois que les octets ont été ACKed.

Mais en même temps, la machine réceptrice n'envoyait pas d'ACK à cause de l'algorithme ACK retardé. Cela met la transmission dans une impasse pendant 200 ms, après quoi la machine réceptrice reçoit finalement les données, ce qui permet ensuite à la fonction d'envoi de recevoir un FD_WRITE.

Bien sûr, tout cela ne se produit pas lorsque j'ai utilisé 8191 octets parce que je n'ai pas rempli tout le tampon, et donc le prochain send() n'a pas bloqué. Cela signifiait que Winsock continuerait toujours à envoyer des données de sorte que l'algorithme ACK retardé ne soit jamais lancé à la réception (sauf sur le dernier paquet s'il s'agit d'un paquet à numéro impair).

Espérons que cela aide quelqu'un d'autre avec le même problème que j'avais.

0

Vérifiez le réglage "Contrôle de flux" sur vos cartes réseau et commutateurs. Si c'est le cas, cela peut être la cause de votre problème.

Et pour une dissection correcte, vous devrez exécuter un "wirehark" aux deux extrémités du transfert.

+0

Je l'ai essayé à nouveau avec Flow Control désactivé sur les deux machines. Même résultatJe vais essayer de refaire le test avec Wireshark sur les deux et publier les logs. – Meta