Question

J'ai lu un exemple de serveur Tcp Echo Server et certaines choses ne me sont pas claires.

TcpClient client = null;
NetworkStream netStream = null;

try {
  client = listener.AcceptTcpClient(); 
  netStream = client.GetStream();

  int totalBytesEchoed = 0;
  while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0) {
    netStream.Write(rcvBuffer, 0, bytesRcvd);
    totalBytesEchoed += bytesRcvd;
  }

  netStream.Close();
  client.Close();
} catch {
  netStream.Close();
}

Lorsque le serveur reçoit un paquet (la boucle while), il lit les données dans rcvBuffer et les écrit dans le flux.

Ce qui me trouble, c’est l’ordre chronologique des messages en communication. Les données écrites avec netStream.Write () sont-elles envoyées immédiatement au client (celui-ci peut-être même encore en train d'envoyer) ou uniquement après que les données déjà écrites dans le flux (par client) soient traitées?

La question suivante peut même clarifier la précédente: Si un client envoie des données en écrivant dans le flux, est-ce que les données déplacées vers la file de messages côté serveur attendent d'être lues pour que le flux soit réellement "vide"? Cela expliquerait pourquoi le serveur peut écrire immédiatement dans un flux - car les données provenant du flux sont en réalité mises en mémoire tampon ailleurs ...?

Était-ce utile?

La solution

Conseil: l'appel de méthode NetworkStream.Read bloque cet exemple.

Le livre est tout à fait correct: l'accès brut aux flux TCP n'implique aucune sorte de "chunking" supplémentaire. et, dans cet exemple par exemple, un seul octet pourrait facilement être traité à la fois. Cependant, la lecture et l'écriture par lots (généralement avec des mémoires tampons exposées) peuvent permettre un traitement plus efficace (souvent à la suite d'appels système moins nombreux). La couche réseau et le matériel réseau utilisent également leurs propres formes de tampons.

Rien ne garantit en réalité que les données écrites à partir de Write () le seront avant la fin de la lecture de plus de Reads (): même si les données sont vidées dans une couche, cela ne signifie pas qu'elles sont vidées dans une autre et il n'y a aucune garantie. que les données ont été renvoyées au client. C’est là que les protocoles de niveau supérieur entrent en jeu.

Avec cet exemple d'écho, les données sont simplement acheminées aussi rapidement que possible. L’écriture et la lecture bloquent en fonction de la pile réseau sous-jacente (les tampons d’émission et de réception en particulier), chacune avec sa propre série de tampons.

[Cela simplifie un peu les choses - on peut toujours regarder le protocole [TCP] lui-même, qui impose des caractéristiques de transmission au flux de paquets réel.]

Autres conseils

Une connexion TCP est, en principe, full duplex. Donc, vous avez deux canaux distincts et oui, les deux côtés pourraient écrire en même temps.

Vous avez raison de dire que techniquement, lorsque vous effectuez l'opération Read (), vous ne lisez pas les bits sur le fil. Vous lisez essentiellement des données mises en mémoire tampon (morceaux reçus par un TCP et classés dans le bon ordre). Lors de l’envoi, vous pouvez utiliser Flush () qui devrait en principe envoyer des données immédiatement, mais les piles TCP modernes ont un peu de logique pour rassembler des données dans des paquets de taille appropriée et les envoyer en rafale.

Comme Henk Holterman l'a expliqué, TCP est un protocole en duplex intégral (si toutes les infrastructures sous-jacentes le prennent en charge). Par conséquent, l'envoi et la réception de données sont plus fréquents lorsque votre serveur / client lit et écrit des données. Ce n'est pas comme si vous envoyiez des données au serveur, un client les lira immédiatement. Le client peut envoyer ses propres données, puis exécuter Read (). Dans ce cas, les données resteront plus longtemps dans la mémoire tampon du réseau et pourront être supprimées après un certain temps si personne ne veut les lire. Au moins, j’ai vécu cela avec ma bibliothèque de serveurs / clients supa dupa (-.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top