4

I've got an TCP Server that listens asynchronously for incoming connections. Everything works fine if just one client is connected. But if there are two or more connections, the Server doesn't get the first message. When i debug the ReceiveCallback function i can see that the Server gets the length of the message but not the data. I.e. if I connect two clients and try to send the first message: "hello", the server gets: received = 5; buffer= /0/0/0/0/0, so nothing is displayed. In the second message of the same client, the server gets the data.

that's how my server looks like:

        private void StartServer()
    {
        try
        {
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, 3333));
            serverSocket.Listen(100);
            serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);   

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }


     private void AcceptCallback(IAsyncResult ar)
    {
        try
        {
            Socket clientSocket = serverSocket.EndAccept(ar); 
            clientSocketList.Add(clientSocket);
            AppendToTextBox("ClientConnected");
            clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), clientSocket);
            serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }


        private void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            int received = 0;
            Socket current = (Socket)ar.AsyncState;
            received = current.EndReceive(ar);
            byte[] data = new byte[received];

            if (received == 0)
            {
                return;
            }

            Array.Copy(buffer, data, received);
            string text = Encoding.ASCII.GetString(data);

            AppendToTextBox(text);
            buffer = null;
            Array.Resize(ref buffer, current.ReceiveBufferSize);

            current.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), current);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
0

1 Answer 1

2

See the example at http://msdn.microsoft.com/en-us/library/dxkwh6zw.aspx

You want to change your code so that it allocates a new buffer each time you call BeginReceive:

        Socket clientSocket = serverSocket.EndAccept(ar); 
        clientSocketList.Add(clientSocket);
        AppendToTextBox("ClientConnected");
        var buffer = new byte[BUFFER_LENGTH];  // <---
        clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), clientSocket);
        serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);

You must have one buffer per client. Otherwise, one client can overwrite the buffer used by the other client.

Sign up to request clarification or add additional context in comments.

1 Comment

You'll probably want to use more than clientSocket for the state parameter of BeginReceive, seeing as your ReceiveCallback is most likely going to need to use buffer in order to interpret the data received. The link that @Jim included demonstrates a solution to this problem by using an instance of a class as the state parameter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.