Je suis implémentant un simple client HTTP qui se connecte simplement à un serveur Web et obtient sa page d'accueil par défaut. Ici, c'est et ça marche bien: Lorsque je supprime la ligne ci-dessous du code ci-dessus, le programme bloque sur sr.readtoend strong>. P>
string req = "";
req += "GET / HTTP/1.0\r\n";
req += "s df slkjfd sdf/ s/fd \\sdf/\\\\dsfdsf \r\n";
req += "qwretyuiopasdfghjkl\r\n";
req += "Host: www.google.com\r\n";
req += "\r\n";
5 Réponses :
essayez d'utiliser system.net.webclient au lieu de system.net.sockets.tcpclient directement:
@Remy Lebeau - merci mais je doit B> utiliser tcpclient parce que je veux le faire en niveau inférieur.
@Remy Lebeau - Ce n'est donc pas une réponse à la question et distrayons les autres parce qu'ils pensent "il a une réponse": /
@isaac - Si vous devez utiliser TCPClient, vous devez vraiment lire les spécifications HTTP réellement sur IETF. org / rfc / rfc2616.txt . Votre code de lecture original ne fonctionnera pas dans de nombreuses situations, comme Readtoend () est le mauvais moyen de les gérer, comme Aziz l'a dit plus tôt.
J'ai trouvé une question dans tout ce que: p>
Comment puis-je lire la réponse et assurez-vous de lire toute la réponse dans la demande HTTP / 1.1? EM> P>
Et c'est une question que je peux répondre! p>
Toutes les méthodes que vous utilisez ici sont synchrones, faciles à utiliser, mais pas même légèrement fiables. Vous verrez des problèmes dès que vous avez une réponse importante et que vous ne faites qu'une partie. P>
Pour mettre en œuvre une connexion TCPClient la plus robuste, vous devez utiliser toutes les méthodes et rappels asynchrones. Les méthodes pertinentes sont les suivantes: p>
1) Créez la connexion avec tcpclient.beginConnect (...) avec le rappel appelant tcpclient.endconnect (...) C'est cette étape finale (appelant à plusieurs reprises Bekread jusqu'à ce que 0 octets soit lu) qui résout le problème de la récupération de la réponse, de toute la réponse, et de rien que la réponse. Alors aidez-nous TCP. P>
espère que cela aide! p>
2) Envoyer une demande avec tcpclient.getstream (). BeginWrite (...) avec le rappel appelant tcpclient.getstream (). Endwrite (...)
3) recevoir une réponse avec tcpclient.getstream (). Beginread (...) avec le rappel appelant tcpclient.getstream (). Endread (...), Ajout du résultat à un tampon StringBuilder, puis appelant tcpclient.getstream ( ) .Beginread (...) à nouveau (avec le même rappel) jusqu'à ce qu'une réponse de 0 octets soit reçue. p>
Je vous suggère d'essayer votre code contre un serveur Web standard et largement testé, bien testé, installé sur votre propre machine locale, tels que Apache httpd ou IIS. P>
Configurez votre serveur Web pour répondre sans l'header hôte em> (par exemple une application Web par défaut dans IIS) et voir si tout va bien. P>
En bas, vous ne pouvez pas vraiment dire ce qui se passe dans les coulisses, car vous ne contrôlez pas les sites Web / applications Web comme Google, Yahoo, etc.
Par exemple, un administrateur de site Web peut configurer le site afin qu'il n'y ait pas d'application par défaut pour les connexions TCP entrantes sur le port 80, à l'aide du protocole HTTP.
Mais il / elle peut souhaiter configurer une application Telnet par défaut lors de la connexion via TCP Port 23, à l'aide du protocole Telnet. P>
Ceci concerne l'utilisation de tcpclient. P>
Je sais que ce post est vieux. Je fournis ces informations juste au cas où quelqu'un d'autre vient à travers cela. Considérez cette réponse à un complément à toutes les réponses ci-dessus. P>
L'en-tête HTTP Host est requis par certains serveurs car ils sont configurés pour accueillir plus d'un domaine par adresse IP. En règle générale, a toujours envoyé l'en-tête hôte. Un bon serveur répondra avec "non trouvé". Certains serveurs ne répondent pas du tout. P>
Lorsque l'appel à lire les données des blocs des flux, c'est généralement parce que le serveur attend que plus de données soient envoyées. Ceci est typiquement le cas lorsque la spécification HTTP 1.1 n'est pas suivie de près. Pour démontrer cela, essayez d'omettre la séquence finale du CR LF, puis de lire les données du flux - l'appel à lire attendra si le client est sorti ou que le serveur abandonne l'attente en terminant la connexion. P>
J'espère que cela met un peu de lumière ... p>
Je crois que READTOEND attendra jusqu'à la fermeture de la connexion. Cependant, cela ne semble pas fermer. Vous devriez le lire continuellement à la place. Ensuite, cela fonctionnera comme vous pouvez vous attendre.
Je ne sais pas si c'est le problème, mais ne devriez-vous pas utiliser la longueur de contenu dans la réponse HTTP pour déterminer le nombre d'octets que vous devriez lire, puis lire ces nombreux octets du corps de la réponse?
@Aziz. Peut-être que c'est une bonne solution au lieu d'utiliser Readtoend B>. Mais dans la première partie de la question, je ne reçois rien (même un octet) du serveur.
Ce code fonctionne ici avec ou sans l'hôte: en-tête. Est-ce que le segment TCP de la demande d'obtenir définir le bit push? - pas que vous puissiez faire beaucoup à ce sujet, mais si ce n'est pas défini, cela pourrait expliquer les retransmissions
@nos - merci nos. J'ai ajouté quelques détails sur votre indice
@Aziz - Quelque chose à garder à l'esprit est que toutes les réponses HTTP dans HTTP 1.1 utilisent du tout une en-tête de "longueur de contenu". Certaines réponses utilisent plutôt un "codage de transfert: chunked", ce qui nécessite un modèle de lecture complètement différent.
Les gars, Telnet n'enverraient certainement pas \ r \ n à héberger au lieu de \ n.