2009-01-26 5 views
11

J'utilise C# .Net et la classe Socket de l'espace de noms System.Net.Sockets. J'utilise les méthodes de réception asynchrones. Je comprends que cela peut être plus facilement fait avec quelque chose comme un service Web; cette question est née de ma curiosité plutôt que d'un besoin pratique.C# stream a reçu toutes les données?

Ma question est: supposons que le client envoie un objet binaire-sérialisé d'une longueur inconnue. Sur mon serveur avec le socket, comment puis-je savoir que l'objet entier a été reçu et qu'il est prêt pour la désérialisation? J'ai envisagé de préfixer l'objet avec la longueur de l'objet en octets, mais cela semble inutile dans le monde .Net. Que se passe-t-il si l'objet est plus grand que le tampon? Comment pourrais-je savoir, 'hé, dois redimensionner le tampon parce que l'objet est trop grand'?

Répondre

11

Vous soit ont besoin du protocole pour être auto-terminaison (comme XML est efficace - vous savez quand vous avez fini de recevoir un document XML quand il ferme l'élément racine) ou vous devez longueur préfixe les données, ou vous avez besoin de l'autre extrémité pour fermer le flux lorsque c'est fait.

Dans le cas d'un protocole auto-terminé, vous devez avoir suffisamment de crochets pour que le code de lecture puisse indiquer quand il est terminé. Avec la sérialisation binaire, vous risquez de ne pas avoir assez de crochets. Longueur-préfixe est de loin la solution la plus simple ici.

4

Si vous utilisez des douilles pures, vous devez connaître la longueur. Sinon, la taille du tampon n'est pas pertinente, car même si vous avez un tampon de la taille de l'ensemble des données, il peut ne pas tout lire - vérifiez la méthode Stream.Read, elle renvoie le nombre de bits réellement lus, Vous devez donc boucler jusqu'à ce que toutes les données soient reçues.

0

Oui, vous ne désérialiserez pas tant que vous n'aurez pas passé tous les octets.

Questions connexes