Async TCP Server for multiple Clients

自作多情 提交于 2019-12-07 09:59:32

问题


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

回答1:


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.



来源:https://stackoverflow.com/questions/15796836/async-tcp-server-for-multiple-clients

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!