Servidor TCP Assíncrono - Aviso de Enquadramento de Mensagens

Eu tenho um servidor de soquete TCP assíncrono em C # que eu fiz usando os wrappers TcpListener / TcpClient para Socket. Eu sou muito novo em redes em geral, então eu não sabia como o TCP trata os dados enviados e como eles não preservam os limites das mensagens. Depois de uma pequena pesquisa, acho que encontrei uma solução sólida, mas estou pensando se alguém tem mais conselhos para mim.

Atualmente os dados que estou enviando são um byte [] de um objeto de classe serializado usando o protobuf (biblioteca de troca de dados do Google)https://code.google.com/p/protobuf/

Depois de serializar meus dados e antes de enviá-los, decidi acrescentar um Int32 de 4 bytes no início da matriz de bytes. Minha idéia é que quando o pacote é enviado para o servidor, ele irá analisar o Int32 e esperar até receber o número de bytes antes de fazer qualquer coisa com os dados, caso contrário, apenas chamando BeginRead novamente.

Aqui está o código que correu antes de eu escrever os dados, e parece funcionar bem, mas estou aberto a qualquer sugestão de desempenho:

public byte[] PackByteArrayForSending(byte[] data)
{
    // [0-3] Packet Length 
    // [3-*] original data

    // Get Int32 of the packet length
    byte[] packetLength = BitConverter.GetBytes(data.Length);
    // Allocate a new byte[] destination array the size of the original data length plus the packet length array size
    byte[] dest = new byte[packetLength.Length + data.Length];

    // Copy the packetLength array to the dest array
    Buffer.BlockCopy(packetLength, 0, dest, 0, packetLength.Length);
    // Copy the data array to the dest array
    Buffer.BlockCopy(data, 0, dest, packetLength.Length, data.Length);

    return dest;
}

Estou um pouco preso no final do servidor. Eu tenho que ler a variável packetLength usando Buffer.BlockCopy para copiar os primeiros 4 bytes e, em seguida, BitConverter.ToInt32 para ler o comprimento que eu deveria estar recebendo. Não tenho certeza se devo ler constantemente os dados recebidos em um objeto Stream específico do cliente ou apenas usar um loop while. Aqui está um exemplo do código que tenho no servidor até o momento:

NetworkStream networkStream = client.NetworkStream;
int bytesRead = networkStream.EndRead(ar);

if (bytesRead == 0)
{
  Console.WriteLine("Got 0 bytes from {0}, marking as OFFLINE.", client.User.Username);
  RemoveClient(client);
}

Console.WriteLine("Received {0} bytes.", bytesRead);

// Allocate a new byte array the size of the data that needs to be deseralized.
byte[] data = new byte[bytesRead];

// Copy the byte array into the toDeserialize buffer
Buffer.BlockCopy(
  client.Buffer,
  0,
  data,
  0,
  bytesRead);

// Read the first Int32 tp get the packet length and then use the byte[4] to get the packetLength
byte[] packetLengthBytes = new byte[4];
Buffer.BlockCopy(
  data,
  0,
  packetLengthBytes,
  0,
  packetLengthBytes.Length);

int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);

// Now what do you recommend?

// If not all data is received, call 
// networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client);
// and preserve the initial data in the client object

Obrigado pelo seu tempo e conselhos, estou ansioso para aprender mais sobre este assunto.

questionAnswers(1)

yourAnswerToTheQuestion