Async TCP Server for multiple Clients

12,108

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.

Share:
12,108
Admin
Author by

Admin

Updated on June 30, 2022

Comments

  • Admin
    Admin almost 2 years

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