C # Socket.BeginReceive / EndReceive

W jakiej kolejności są wywoływane funkcje Socket.BeginReceive / EndReceive?

Na przykład dzwonięBeginReceive dwa razy, raz, aby uzyskać długość wiadomości, a drugi raz, aby pobrać wiadomość. Teraz scenariusz jest taki, że dla każdej wysyłanej przeze mnie wiadomości zaczynam czekać na jej zakończenie (właściwie potwierdzenie wysłanej wiadomości, czekam też na zakończenie akcji po otrzymaniu potwierdzenia), więc dzwonięBeginReceive z każdymBeginSend, ale w każdymBeginReceivewywołanie zwrotne, sprawdzam, czy otrzymuję długość lub wiadomość. Jeśli otrzymuję wiadomość i otrzymałem ją w całości, nazywam ją innąBeginReceive otrzymać zakończenie akcji. To jest, gdy rzeczy się nie synchronizują. Ponieważ jeden z moich wywołań zwrotnych odbiera bajty, które interpretuje jako długość wiadomości, gdy w rzeczywistości jest to sama wiadomość.

Teraz jak to rozwiązać?

EDYTOWAĆ: To jest pytanie C # .NET :)

Oto kod, w zasadzie jest za duży, przepraszam za to

public void Send(string message)
{
    try
    {
        bytesSent = 0;

        writeDataBuffer = System.Text.Encoding.ASCII.GetBytes(message);
        writeDataBuffer = WrapMessage(writeDataBuffer);
        messageSendSize = writeDataBuffer.Length;

        clientSocket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None,
                            new AsyncCallback(SendComplete), clientSocket);
    }
    catch (SocketException socketException)
    {
        MessageBox.Show(socketException.Message);
    }
}

public void WaitForData()
{
    try
    {
        if (!messageLengthReceived)
        {
            clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, MESSAGE_LENGTH_SIZE - bytesReceived,
                                    SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket);
        }
}

public void Send(string message)
{
    try
    {
        bytesSent = 0;

        writeDataBuffer = System.Text.Encoding.ASCII.GetBytes(message);
        writeDataBuffer = WrapMessage(writeDataBuffer);
        messageSendSize = writeDataBuffer.Length;

        clientSocket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None,
                            new AsyncCallback(SendComplete), clientSocket);
    }
    catch (SocketException socketException)
    {
        MessageBox.Show(socketException.Message);
    }
}

public void WaitForData()
{
    try
    {
        if (! messageLengthReceived)
        {
            clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, MESSAGE_LENGTH_SIZE - bytesReceived,
                                    SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket);
        }
        else 
        {
            clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, messageLength - bytesReceived,
                                    SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket);
        }
    }
    catch (SocketException socketException)
    {
        MessageBox.Show(socketException.Message);
    }
}

public void RecieveComplete(IAsyncResult result)
{
    try
    {
        Socket socket = result.AsyncState as Socket;
        bytesReceived = socket.EndReceive(result);

        if (! messageLengthReceived)
        {
            if (bytesReceived != MESSAGE_LENGTH_SIZE)
            {
                WaitForData();
                return;
            }

            // unwrap message length
            int length = BitConverter.ToInt32(receiveDataBuffer, 0);
            length = IPAddress.NetworkToHostOrder(length);

            messageLength = length;
            messageLengthReceived = true;

            bytesReceived = 0;

            // now wait for getting the message itself
            WaitForData();
        }
        else
        {
            if (bytesReceived != messageLength)
            {
                WaitForData();
            }
            else
            {
                string message = Encoding.ASCII.GetString(receiveDataBuffer);

                MessageBox.Show(message);

                bytesReceived = 0;
                messageLengthReceived = false;

                // clear buffer
                receiveDataBuffer = new byte[AsyncClient.BUFFER_SIZE];

                WaitForData();
            }
        }
    }
    catch (SocketException socketException)
    {
        MessageBox.Show(socketException.Message);
    }

}

public void SendComplete(IAsyncResult result)
{
    try
    {
        Socket socket = result.AsyncState as Socket;
        bytesSent = socket.EndSend(result);

        if (bytesSent != messageSendSize)
        {
            messageSendSize -= bytesSent;

            socket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None,
                            new AsyncCallback(SendComplete), clientSocket);
            return;
        }

        // wait for data
        messageLengthReceived = false;
        bytesReceived = 0;

        WaitForData();
    }
    catch (SocketException socketException)
    {
        MessageBox.Show(socketException.Message);
    }
}

questionAnswers(5)

yourAnswerToTheQuestion