Pregunta

He leído un ejemplo de un servidor de eco Tcp y algunas cosas no están claras para mí.

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();
}

Cuando el servidor recibe un paquete (el bucle while), lee los datos en rcvBuffer y los escribe en la secuencia.

Lo que me confunde es el orden cronológico de los mensajes en comunicación. Los datos que se escribieron con netStream.Write () se enviaron de inmediato al cliente (que aún puede estar enviando), o solo después de que se procesen los datos que ya están escritos en la transmisión (por cliente).

La siguiente pregunta puede incluso aclarar lo anterior: si un cliente envía algunos datos al escribir en la secuencia, ¿se están moviendo los datos a la cola de mensajes en el lado del servidor esperando que la secuencia esté en realidad " vacía " ;? Eso explicaría por qué el servidor puede escribir inmediatamente en la transmisión, porque los datos que provienen de la transmisión en realidad están almacenados en un búfer en otro lugar ...

¿Fue útil?

Solución

Sugerencia: el método llamado NetworkStream.Read está bloqueando en ese ejemplo.

El libro es absolutamente correcto: el acceso directo a las transmisiones TCP no implica ningún tipo de " fragmentación " y, en este ejemplo, por ejemplo, un solo byte podría procesarse fácilmente a la vez. Sin embargo, realizar la lectura y escritura en lotes (normalmente con búferes expuestos) puede permitir un procesamiento más eficiente (a menudo como resultado de menos llamadas al sistema). La capa de red y el hardware de la red también emplean sus propias formas de buffers.

En realidad, no hay garantía de que los datos escritos desde Write () se escriban antes de que se completen con éxito más Reads (): incluso si los datos se eliminan en una capa, no significa que se eliminen en otra y no hay ninguna garantía. que los datos han regresado al cliente. Aquí es donde entran en juego los protocolos de nivel superior.

Con este ejemplo de eco, los datos simplemente se envían lo más rápido posible. Tanto la Escritura como la Lectura se bloquearán según la pila de red subyacente (en particular, los buffers de envío y recepción), cada uno con su propia serie de buffers.

[Esto simplifica un poco las cosas, por supuesto, siempre se puede ver el [protocolo] TCP en sí mismo, lo que impone características de transmisión en el flujo real de paquetes.]

Otros consejos

Una conexión TCP es, en principio, dúplex completo. Así que estás tratando con 2 canales separados y sí, ambos lados podrían estar escribiendo al mismo tiempo.

Tiene razón en que, técnicamente, al realizar la operación de Lectura (), no está leyendo bits del cable. Básicamente, estás leyendo datos almacenados en búfer (fragmentos recibidos por un TCP y ordenados en un orden correcto). Al enviar, puede usar Flush () que, en teoría, debería enviar datos inmediatamente, pero las pilas TCP modernas tienen un poco de lógica sobre cómo recopilar datos en paquetes de tamaño adecuado y enviarlos al cable.

Como explicó Henk Holterman, TCP es un protocolo dúplex completo (si es compatible con toda la infraestructura subyacente), por lo que el envío y la recepción de datos son más frecuentes cuando el servidor / cliente lee y escribe datos. No es como cuando el servidor envía datos, un cliente lo leerá inmediatamente. El cliente puede enviar sus propios datos y luego realizar Lectura (), en este caso los datos permanecerán en el búfer de la red por más tiempo y se podrán descartar después de un tiempo que nadie quiera leerlos. Al menos he experimentado esto al tratar con mi biblioteca supa dupa server / client (-.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top