2009-12-01 4 views
2

J'écris un client HTTP en utilisant le .Net TcpClient/Sockets. Jusqu'ici, le client gère à la fois les réponses Content-Length et Chunked en itérant à travers la réponse NetworkStream (après avoir écrit une requête GET au TcpClient), en analysant les en-têtes et en récupérant les octets/octets du message. Pour ce faire, il utilise la méthode NetworkStream ReadByte..NET C# TcpClient/Socket Performance/efficacité du client HTTP

Tout cela fonctionne très bien, mais la performance est une considération clé de l'application et je voudrais la rendre aussi rapide et efficace que possible. Initialement, cela impliquera de remplacer ReadByte for Read pour le corps du message (basé sur Content-Length) ou la récupération de l'octet corps du message dans un tampon de taille appropriée, en utilisant ReadByte dans toutes les autres zones (telles que lire les en-têtes, tailles de blocs). etc).

Je suis curieux de connaître les meilleures façons de faire cela afin d'obtenir des performances optimales. Évidemment, le principal problème avec HTTP est de ne pas connaître la longueur du flux de réponse à moins qu'il ne soit analysé au fur et à mesure qu'il est récupéré.

Il ya des raisons spécifiques pour lesquelles je n'utilise pas plus de classes abstraites (par exemple HttpWebRequest) pour cela (j'ai besoin d'un meilleur contrôle au niveau de la socket).

Merci beaucoup,

Chris

+0

BTW Je suis curieux - vous avez mentionné que vous avez besoin d'un contrôle fin sur le Socket/Connection, c'est pourquoi vous n'utilisez pas HttpWebRequest. pouvez-vous nous dire ces raisons? – feroze

+0

Je veux simuler un nombre (disons 200) de clients web et pour cela je veux que chaque client fonctionne comme un thread qui gère sa propre connexion, en le gardant ouvert pendant un certain nombre de demandes différentes, en faisant une pause, etc. le client atteindra le même point final (fonctionnalité très similaire aux outils de test de charge standard). Je ne crois pas que HttpWebRequest puisse y parvenir car les connexions sont gérées via le point de service qui arrête ce niveau de contrôle granulaire? – Chris

+0

Désolé, je devrais également dire que j'ai besoin de capturer des informations telles que le temps de premier octet, le nombre de reconnexion, etc ... – Chris

Répondre

1

Je suggère d'utiliser un processus avec un tampon de taille moyenne. Remplissez de manière répétée le tampon jusqu'à la fin du flux de réponse. Lorsque le tampon est plein ou que le flux se termine, attachez ce contenu à la chaîne (ou à tout ce que vous utilisez pour stocker le message).

Si vous voulez lire un élément d'information important au début du flux, lisez juste assez de flux pour le voir. (En d'autres termes, vous n'avez pas besoin de remplir le tampon lors du premier passage si vous ne le souhaitez pas.)

Vous devez également envisager d'utiliser un système d'événements pour signaler la présence de nouvelles données, qui ont été façonné de telle manière que la partie principale de votre processus n'a pas besoin de savoir quoi que ce soit à propos de l'origine des données ou comment vous les mettez en mémoire tampon.

Modifier

En réponse à votre question de commentaire, si vous avez une connexion que vous essayez de réutiliser pour de multiples demandes, vous devez créer un fil qui lit encore et. Lorsqu'il trouve des données, il utilise l'événement pour l'extraire de la partie principale de votre programme. Je n'ai pas d'échantillon à portée de main, mais vous devriez pouvoir en trouver plusieurs avec quelques recherches bing ou google.

+0

Merci John. Si j'utilise un tampon cependant, je suppose que je dois utiliser Read() qui bloquera quand la fin du flux sera dépassée. Je dois continuer tout de suite quand le dernier octet est lu pour faire l'analyse syntaxique de la réponse, etc. En outre, avez-vous des exemples/liens vers un système basé sur des événements similaires? Merci! – Chris

+0

Vous pouvez empêcher le blocage si vous envoyez "Connection: close" dans le cadre de la demande. –

+0

Malheureusement, il est également important de réutiliser les connexions/garder les vies ... – Chris