C # Socket. Recibir longitud del mensaje

Actualmente estoy en el proceso de desarrollar un servidor de C # Socket que puede aceptar múltiples conexiones desde múltiples computadoras cliente. El objetivo del servidor es permitir a los clientes "suscribirse" y "darse de baja" de los eventos del servidor.

Hasta ahora he echado un buen vistazo aquí:http: //msdn.microsoft.com/en-us/library/5w7b7x5f (v = VS.100) .aspx yhttp: //msdn.microsoft.com/en-us/library/fx6588te.asp para ideas.

Todos los mensajes que envío están encriptados, así que tomo el mensaje de cadena que deseo enviar, lo convierto en una matriz de bytes [] y luego encripto los datos antes de pre-pendiente de la longitud del mensaje a los datos y enviarlos a través del conexión

Una cosa que me parece un problema es esta: en el extremo receptor parece posible que Socket.EndReceive () (o la devolución de llamada asociada) pueda regresar cuando solo se haya recibido la mitad del mensaje. ¿Existe una manera fácil de garantizar que cada mensaje se reciba "completo" y solo un mensaje a la vez?

EDITAR Por ejemplo, supongo que los sockets .NET / Windows no "ajustan" los mensajes para garantizar que un solo mensaje enviado con Socket.Send () se reciba en una llamada Socket.Receive ()? ¿O lo hace?

Mi implementación hasta ahora:

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

Respuestas a la pregunta(4)

Su respuesta a la pregunta