C#TcpListener - 客户端编号有限

问题描述 投票:1回答:1

亲爱的Stack Overflow社区,

我目前正在开发一个C#的在线TCG。服务器在我自己的机器上运行得很好(四核,八线程Windows 7)。我可以毫无问题地连接12个客户端。但是当我在服务器上启动它时,最大客户端数量将限制为计算机上的处理器核心数量。我在单核Windows 2016 Server上运行代码,无法连接多个客户端来启动游戏。然后我在四核Windows 2012 Server上运行服务器,只能连接四个客户端并启动两个游戏。任何其他客户端完全被忽略,直到有人断开连接。然后新客户端被接受,服务器崩溃。

该服务器是带有.NET Framework 4.0的MS Visual Studio 2015 Windows窗体应用程序。 Windows Server计算机具有.NET Framework 4.0,我自己的计算机具有4.5版。

我很乐意提供您可能需要的任何其他信息并回答您的所有问题。

C#中的服务器代码:

public void Init()
{
    try {
        server = new TcpListener(IPAddress.Any, port);
        server.Start();
        serverRunning = true;
        server.BeginAcceptTcpClient(AcceptTcpClient, server);
        OutputTB.Text = "server has been started on port " + port.ToString();
    }
    catch (Exception e) {
        OutputTB.Text = "socket error: " + e.Message;
    }
}

private void AcceptTcpClient(IAsyncResult newClient)
{
    if (!serverRunning)
        return;
    server.BeginAcceptTcpClient(AcceptTcpClient, server);

    TcpListener listener = (TcpListener)newClient.AsyncState;
    ServerClient client = new ServerClient(listener.EndAcceptTcpClient(newClient));
    Send("SWHO", client);
    connectedClients.Add(client);
    Invoke((MethodInvoker)delegate {
        ClientListBox.Items.Add("Waiting for authentification...");
    });

    NetworkStream stream = client.tcp.GetStream();
    StreamReader reader = new StreamReader(stream, true);
    while (client.connected && serverRunning) {
        if (stream.DataAvailable) {
            string data = reader.ReadLine();
            if (data != null)
                OnIncomingData(client, data);
        }
    }
    Invoke((MethodInvoker)delegate {
        if (client.authenticated)
            ClientListBox.Items.Remove(client.playerName);
        else
            ClientListBox.Items.Remove("Waiting for authentification...");
    });
    Send("SDISC", client);
    waitingClients.Remove(client);
    connectedClients.Remove(client);
    client.tcp.Close();
}

private void OnIncomingData()
{
    //process client data
}
c# .net server tcplistener
1个回答
0
投票

线程池耗尽它!非常感谢itsme86和usr提供的有用提示。现在代码看起来像这样:

private void AcceptTcpClient(IAsyncResult ar)
{
    server.BeginAcceptTcpClient(AcceptTcpClient, server);
    Task.Run(() => ListenToIncomingData(IAsyncResult ar);
}

有一点我很好奇:异步调用是否也消耗了一个线程?怎么会有足够的资源来处理它,但还不足以处理未完成的回调?

© www.soinside.com 2019 - 2024. All rights reserved.