Boucle jusqu'à la réponse complète de TcpClient
J'ai écrit un simple TCP client et le serveur. Le problème se trouve avec le client.
J'ai un peu de mal à lire l'intégralité de la réponse du serveur. Je dois laisser le fil de sommeil afin de permettre que toutes les données seront envoyées.
J'ai essayé quelques fois de convertir ce code dans une boucle qui s'exécute jusqu'à ce que le serveur est la fin de l'envoi des données.
//Init & connect to client
TcpClient client = new TcpClient();
Console.WriteLine("Connecting.....");
client.Connect("192.168.1.160", 9988);
//Stream string to server
input += "\n";
Stream stm = client.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(input);
stm.Write(ba, 0, ba.Length);
//Read response from server.
byte[] buffer = new byte[1024];
System.Threading.Thread.Sleep(1000); //Huh, why do I need to wait?
int bytesRead = stm.Read(buffer, 0, buffer.Length);
response = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine("Response String: "+response);
client.Close();
source d'informationauteur jim
Vous devez vous connecter pour publier un commentaire.
La nature des flux qui sont construits sur des sockets, c'est que vous avez ouvert un pipeline qui transmet et reçoit des données jusqu'à ce que le socket est fermé.
Toutefois, en raison de la nature de client/serveur interactions, ce pipeline n'est pas toujours la garantie d'avoir du contenu à lire. Le client et le serveur doivent accepter d'envoyer du contenu sur le gazoduc.
Quand vous prenez le
Stream
dans l'abstraction .NET et la superposer sur le concept de sockets, l'exigence d'un accord entre le client et le serveur s'applique toujours; vous pouvez appelerStream.Lire
tout ce que vous voulez, mais si la prise de votreStream
est connecté sur l'autre côté n'est pas l'envoi de contenu, l'appel sera juste attendre qu'il y est contenu.C'est pourquoi les protocoles existent. Au niveau le plus fondamental, elles aident à définir ce qu'est un message qui est envoyé entre les deux parties. Généralement, le mécanisme est quelque chose le long des lignes de:
Cela dit vous n'êtes pas adhérent à la ci-dessus; votre appel à
Stream.Read
est juste de dire "lire 1024 octets" alors qu'en réalité, il pourrait ne pas être de 1024 octets à lire. Si c'est le cas, l'appel àStream.Read
se bloque jusqu'à ce que l'été renseigné.La raison de l'appel à
Thread.Le sommeil
fonctionne probablement est parce que le temps d'une seconde passe par, leStream
a 1024 octets à lire et il ne bloque pas.En outre, si vous voulez vraiment lire 1024 octets, vous ne pouvez pas supposer que l'appel à
Stream.Read
remplira 1024 octets de données. La valeur de retour de laStream.Read
méthode vous indique combien d'octets ont été lus en réalité. Si vous avez besoin de plus de votre message, vous avez besoin de faire appel à d'autresStream.Read
.Jon Skeet a écrit exactement de la même façon pour ce faire si vous voulez un échantillon.
Essayer de répéter la
tout bytesRead > 0. Il est commun pour que je me souviens.
Bien sûr, n'oubliez pas de passer appropriée paramètres de mémoire tampon.
Vous ne connaissez pas la taille des données que vous pourrez lire si vous avez mis en place un mécanisme de décider. L'un est le délai d'attente et un autre est à l'aide de séparateurs.
Sur votre exemple vous lire ce que les données d'une seule itération(lire) parce que vous n'avez pas de définir le délai d'attente pour la lecture et l'utilisation de la valeur par défaut c'est "0" milisecond. Donc, vous avez à dormir juste 1000 ms. Vous obtenez le même effet avec l'aide de recevoir de temps à 1000 ms.
Je pense à l'aide de la longueur de données en tant que préfixe n'est pas la vraie solution, car lors de la socket est fermée par les deux parties, socket time-wait situation ne peut pas manipulé correctement. Même les données peuvent être envoyer au serveur et à la cause du serveur pour obtenir de l'exception . Nous avons utilisé le préfixe-caractère de fin de séquence. Après chaque lecture, nous vérifions les données de début et de fin de la séquence de caractères, si nous ne pouvons pas obtenir la fin de caractères, nous appelons à une autre lecture. Mais bien sûr, cela ne fonctionne que si vous avez le contrôle du côté serveur et côté client code.
Dans le protocole TCP Client /Serveur, j'ai juste écrit que je générer le paquet que je veux envoyer à un flux de mémoire, puis prendre la longueur de ce cours d'eau et l'utiliser comme un préfixe lors de l'envoi des données. De cette façon, le client sait combien d'octets de données, il va avoir besoin de lire pour un paquet complet.