Question

Pour mon projet actuel, je dois demander des données XML via une connexion de socket TCP / IP. Pour cela, j'utilise la classe TcpClient:

Dim client As New TcpClient()
client.Connect(server, port)

Dim stream As NetworkStream = client.GetStream()
stream.Write(request)
stream.Read(buffer, 0, buffer.length)

// Output buffer and return results...

Maintenant, cela fonctionne très bien pour les petites réponses. Cependant, lorsque je commence à recevoir des blocs de données plus volumineux, il apparaît que les données sont poussées en rafales sur la connexion par socket. Lorsque cela se produit, l’appel stream.Read ne lit que la première rafale, ce qui me laisse manquer le reste de la réponse.

Quelle est la meilleure façon de gérer ce problème? Au départ, j’essayais de faire une boucle jusqu’à ce que j’aie un document XML valide, mais j’ai trouvé que, entre les appels stream.Read, le flux sous-jacent s’arrêtait parfois et que je manquais la dernière partie des données.

Était-ce utile?

La solution

Vous créez une boucle pour la lecture.

Stream.Read renvoie int pour les octets déjà lus ou 0 si la fin du flux est atteinte.

Donc, ça ressemble à:

int bytes_read = 0;
while (bytes_read < buffer.Length)
   bytes_read += stream.Read(buffer, bytes_read, buffer.length - bytes_read);

EDIT: maintenant, la question est de savoir comment vous déterminez la taille du tampon. Si votre serveur envoie d'abord la taille, vous pouvez utiliser l'extrait de code ci-dessus. Mais si vous devez lire jusqu’à ce que le serveur ferme la connexion, vous devez alors utiliser try / catch (ce qui est une bonne idée même si vous connaissez la taille) et utilisez bytes_read pour déterminer ce que vous avez reçu.

int bytes_read = 0;
try
{
   int i = 0;
   while ( 0 < (i = stream.Read(buffer, bytes_read, buffer.Length - bytes_read) )
      bytes_read += i;
}
catch  (Exception e)
{
//recover
}
finally
{
if (stream != null)
   stream.Close();
}

Autres conseils

La lecture n’est pas garantie pour lire complètement le flux. Il renvoie le nombre d'octets lus et 0 s'il n'y a plus d'octets à lire. Continuez à lire en boucle pour lire toutes les données hors du flux.

Je vous conseille vivement d'essayer la WCF pour de telles tâches. Après une courbe d'apprentissage moins abrupte, il vous offre de nombreux avantages par rapport aux communications brutes par socket. Pour la tâche à accomplir, je suis d’accord avec les réponses précédentes, vous devez utiliser une boucle et allouer dynamiquement de la mémoire selon les besoins.

C’est un moyen possible de le faire et d’obtenir une "réponse". la chaîne de réponse. Si vous avez besoin du tableau d'octets, enregistrez simplement ms.ToArray ().

string response;

TcpClient client = new TcpClient();
client.Connect(server, port);
using (NetworkStream ns = c.GetStream())
using (MemoryStream ms = new MemoryStream())
{
    ns.Write(request);

    byte[] buffer = new byte[512];
    int bytes = 0;

    while(ns.DataAvailable)
    {
        bytes = ns.Read(buffer,0, buffer.Length);
        ms.Write(buffer, 0, bytes);
    }

    response = Encoding.ASCII.GetString(ms.ToArray());
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top