异步TCP服务器为多个客户端 [英] Async TCP Server for multiple Clients

查看:234
本文介绍了异步TCP服务器为多个客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有异步侦听传入连接的TCP服务器。如果只有一个客户端连接一切正常。但是,如果有两个或多个连接,服务器没有得到的第一个消息。当我调试ReceiveCallback功能,我可以看到服务器获取消息的长度,而不是数据。即如果我连接两个客户端,并尝试发送的第一条消息:你好,服务器得到:接受= 5;缓冲= / 0/0/0/0/0,因此不会显示任何内容。在相同的客户端的所述第二消息,所述服务器获取数据。

这是我的服务器的样子:

 私人无效startserver的()
    {
        尝试
        {
            ServerSocket的=新的Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            serverSocket.Bind(新IPEndPoint(IPAddress.Any,3333));
            serverSocket.Listen(100);
            serverSocket.BeginAccept(新的AsyncCallback(AcceptCallback),NULL);        }
        赶上(异常前)
        {
            MessageBox.Show(ex.Message,Application.ProductName,MessageBoxButtons.OK,MessageBoxIcon.Error);
        }
    }
     私人无效AcceptCallback(IAsyncResult的AR)
    {
        尝试
        {
            插座ClientSocket的= serverSocket.EndAccept(AR);
            clientSocketList.Add(ClientSocket的);
            AppendToTextBox(ClientConnected);
            clientSocket.BeginReceive(缓冲液,0,buffer.Length,SocketFlags.None,新的AsyncCallback(ReceiveCallback),ClientSocket的);
            serverSocket.BeginAccept(新的AsyncCallback(AcceptCallback),NULL);        }
        赶上(异常前)
        {
            MessageBox.Show(ex.Message,Application.ProductName,MessageBoxButtons.OK,MessageBoxIcon.Error);
        }
    }
        私人无效ReceiveCallback(IAsyncResult的AR)
    {
        尝试
        {
            INT接收= 0;
            插座电流=(插座)ar.AsyncState;
            收到= current.EndReceive(AR);
            字节[]数据=新的字节[收]            若(收到== 0)
            {
                返回;
            }            Array.Copy(缓冲,数据接收);
            字符串文本= Encoding.ASCII.GetString(数据);            AppendToTextBox(文本);
            缓冲= NULL;
            Array.Resize(参考缓冲器,current.ReceiveBufferSize);            current.BeginReceive(缓冲,0,buffer.Length,SocketFlags.None,新的AsyncCallback(ReceiveCallback),电流);
        }
        赶上(异常前)
        {
            MessageBox.Show(ex.Message,Application.ProductName,MessageBoxButtons.OK,MessageBoxIcon.Error);
        }
    }


解决方案

参见的 http://msdn.microsoft.com/en-us/library/dxkwh6zw.aspx

您想改变你的code,使其在每次调用时分配一个新的缓冲 BeginReceive

 插座ClientSocket的= serverSocket.EndAccept(AR);
        clientSocketList.Add(ClientSocket的);
        AppendToTextBox(ClientConnected);
        VAR缓冲=新的字节[BUFFER_LENGTH] //< ---
        clientSocket.BeginReceive(缓冲液,0,buffer.Length,SocketFlags.None,新的AsyncCallback(ReceiveCallback),ClientSocket的);
        serverSocket.BeginAccept(新的AsyncCallback(AcceptCallback),NULL);

您必须有每个客户端一个缓冲区。否则,一个客户端可以覆盖由其他客户使用的缓冲区。

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

解决方案

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.

这篇关于异步TCP服务器为多个客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆