C # Socket.Receive comprimento da mensagem

No momento, estou desenvolvendo um servidor C # Socket que pode aceitar várias conexões de vários computadores clientes. O objetivo do servidor é permitir que os clientes "inscrevam-se" e "cancelem a inscrição" nos eventos do servido

Até agora, dei uma boa olhada aqui:http: //msdn.microsoft.com/en-us/library/5w7b7x5f (v = VS.100) .aspx ehttp: //msdn.microsoft.com/en-us/library/fx6588te.asp para idéias.

Todas as mensagens enviadas são criptografadas; portanto, pego a string que desejo enviar, converto-a em uma matriz de bytes [] e, em seguida, criptografamos os dados antes de pré-pendurar o comprimento da mensagem nos dados e enviá-los pelo conexão

Uma coisa que me parece um problema é a seguinte: no lado de recebimento, parece possível que Socket.EndReceive () (ou o retorno de chamada associado) possa retornar quando apenas metade da mensagem for recebida. Existe uma maneira fácil de garantir que cada mensagem seja recebida "concluída" e apenas uma mensagem por vez?

EDITAR Por exemplo, acho que os soquetes .NET / Windows não "encapsulam" as mensagens para garantir que uma única mensagem enviada com Socket.Send () seja recebida em uma chamada Socket.Receive ()? Ou faz?

inha implementação até agora:

private void StartListening()
{
    IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
    IPEndPoint localEP = new IPEndPoint(ipHostInfo.AddressList[0], Constants.PortNumber);

    Socket listener = new Socket(localEP.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    listener.Bind(localEP);
    listener.Listen(10);

    while (true)
    {
        // Reset the event.
        this.listenAllDone.Reset();

        // Begin waiting for a connection
        listener.BeginAccept(new AsyncCallback(this.AcceptCallback), listener);

        // Wait for the event.
        this.listenAllDone.WaitOne();
    }
}

private void AcceptCallback(IAsyncResult ar)
{
    // Get the socket that handles the client request.
    Socket listener = (Socket) ar.AsyncState;
    Socket handler = listener.EndAccept(ar);

    // Signal the main thread to continue.
    this.listenAllDone.Set();

    // Accept the incoming connection and save a reference to the new Socket in the client data.
    CClient client = new CClient();
    client.Socket = handler;

    lock (this.clientList)
    {
        this.clientList.Add(client);
    }

    while (true)
    {
        this.readAllDone.Reset();

        // Begin waiting on data from the client.
        handler.BeginReceive(client.DataBuffer, 0, client.DataBuffer.Length, 0, new AsyncCallback(this.ReadCallback), client);

        this.readAllDone.WaitOne();
    }
}

private void ReadCallback(IAsyncResult asyn)
{
    CClient theClient = (CClient)asyn.AsyncState;

    // End the receive and get the number of bytes read.
    int iRx = theClient.Socket.EndReceive(asyn);
    if (iRx != 0)
    {
        // Data was read from the socket.
        // So save the data 
        byte[] recievedMsg = new byte[iRx];
        Array.Copy(theClient.DataBuffer, recievedMsg, iRx);

        this.readAllDone.Set();

        // Decode the message recieved and act accordingly.
        theClient.DecodeAndProcessMessage(recievedMsg);

        // Go back to waiting for data.
        this.WaitForData(theClient);
    }         
}

questionAnswers(4)

yourAnswerToTheQuestion