Pergunta

Eu li um exemplo de uma rede TCP Echo Server e algumas coisas não são claras para mim.

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

Quando o servidor recebe um pacote (o loop while), ele lê os dados em rcvBuffer e grava-lo para o fluxo.

O que me confunde é a ordem cronológica de mensagens na comunicação. São os dados que foi escritos com netStream.Write () enviada imediatamente para o cliente (que pode até ainda estar enviando), ou somente após os dados que já está escrito para o fluxo (por cliente) processados.

A seguinte pergunta pode até esclarecer a anterior: Se um cliente envia alguns dados, por escrito para o fluxo, é que os dados movidos para a fila de mensagens no lado do servidor esperando para ser lido de modo que o fluxo é realmente "vazio"? Isso explicaria por que o servidor pode imediatamente escrever a stream -? Porque os dados que vem do fluxo é realmente tamponada outro lugar ...

Foi útil?

Solução

Dica:. A chamada de método NetworkStream.Read está bloqueando nesse exemplo

O livro é absolutamente correto - Acesso cru para TCP córregos não implica qualquer tipo de extra "chunking" e, neste exemplo, por exemplo, um único byte poderia facilmente ser processado de cada vez. No entanto, executar a leitura e escrita em lotes (normalmente com buffers expostos) pode permitir o processamento mais eficiente (muitas vezes como resultado de chamadas de sistema menos). A camada de rede e hardware de rede também empregam lá próprias formas de buffers.

Na verdade não há garantia de que os dados gravados a partir Write () vai realmente ser escrito antes de mais Lê () concluir com êxito: mesmo se dados são liberados em uma camada não implica que é liberado em outra e não há absolutamente nenhuma garantia que os dados fez o seu caminho de volta para o cliente. Este é o lugar onde protocolos de nível superior entram em jogo.

Com este exemplo echo os dados são simplesmente empurrou através tão rápido quanto ele pode ser. Tanto a gravação ea leitura irá bloquear com base na pilha de rede subjacente (a enviar e receber buffers, em particular), cada um com suas próprias séries de buffers.

[Isso simplifica as coisas um pouco, é claro -. Pode-se sempre olhar para o TCP [protocolo] em si, que impõe características de transmissão no fluxo de pacotes real]

Outras dicas

Uma conexão TCP é, em princípio, full duplex. Então, você está lidando com 2 canais separados e, sim, ambos os lados poderia estar escrevendo ao mesmo tempo.

Está certo que tecnicamente ao executar a operação Read (), você não está lendo pedaços fora do fio. Você está lendo basicamente dados em buffer (pedaços recebido por um TCP e dispostas em uma ordem correta). Ao enviar você pode flush () que deveria, em teoria, deve enviar dados imediatamente, mas modernas pilhas TCP tem um pouco de lógica como reunir dados em pacotes de tamanho apropriado e estourá-los para o fio.

Como Henk Holterman explicou, TCP é um protocolo full duplex (se suportado por todos infraestrutura subjacente), então o envio e recebimento de dados é mais quando você servidor / cliente lê e grava dados. Não é como quando você dados do servidor de envio, um cliente vai lê-lo imediatamente. Cliente pode ser o envio de seu próprio dados e, em seguida, executar Read (), neste caso, os dados ficarão em rede tampão mais tempo e pode ser descartado depois de algum tempo que ninguém quer ler. Pelo menos eu experimentei isso quando se lida com a minha biblioteca do servidor supa dupa / cliente (-.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top