繁体   English   中英

TCP服务器高CPU使用率

[英]TCP Server high CPU usage

C#Visual Studio 2013年

我正在使用粗糙的TCP Server / Client。 它是这样的:
客户端向服务器发送消息>服务器向客户端发送“响应”。 我要循环使用此数据,因为我要在游戏中将这种数据传输用于多人游戏。 但是,我进行了性能测试,因为当连接了三个以上的客户端时,我的TCP Server正在使用大量的CPU。 性能分析器表示,以下方法可导致96%的利用率。 你能帮我解决这个问题吗?

private static void ReceiveCallback(IAsyncResult AR)
    {
        Socket current = (Socket)AR.AsyncState;
        int received;

        try
        {
            received = current.EndReceive(AR);
        }
        catch (SocketException)
        {
            Console.WriteLine("Client forcefully disconnected");
            current.Close(); // Dont shutdown because the socket may be disposed and its disconnected anyway
            _clientSockets.Remove(current);
            return;
        }

        byte[] recBuf = new byte[received];
        Array.Copy(_buffer, recBuf, received);
        string text = Encoding.ASCII.GetString(recBuf);
        Console.WriteLine("Received Text: " + text);


        string msg = "Response!";
        byte[] data = Encoding.ASCII.GetBytes(msg);
        current.Send(data);


        current.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
    }

以防万一,这是调用ReceiveCallback的AcceptCallback方法。

private static void AcceptCallback(IAsyncResult AR)
    {
        Socket socket;

        try
        {
            socket = _serverSocket.EndAccept(AR);
        }
        catch (ObjectDisposedException) // I cannot seem to avoid this (on exit when properly closing sockets)
        {
            return;
        }

        _clientSockets.Add(socket);
        socket.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
        Console.WriteLine("Client connected...");
        _serverSocket.BeginAccept(AcceptCallback, null);
    } 

在注释中,您说您的代码发送数据的速度与CPU和网络允许的速度一样快,但是您希望限制它。 您可能应该考虑要发送的最佳频率。 然后,以该频率发送。

var delay = TimeSpan.FromMilliseconds(50);
while (true) {
 await Task.Delay(delay);
 await SendMessageAsync(mySocket, someData);
 await ReceiveReplyAsync(mySocket);
}

注意,我已经使用了await来整理回调混乱。 如果现在将计时器或延迟添加到混合回调中,可能会变得笨拙。 您可以按照自己喜欢的任何方式进行操作。 或者,您仅在后台线程/任务上使用同步套接字IO。 如果没有太多线程,那将是更简单和首选的方式。 请注意,MSDN通常没有充分的理由将APM模式与套接字一起使用。

请注意,如果要基于时间等待,则完全可以使用Thread.Sleep / Task.Delay。

你为什么做这个 :

byte[] recBuf = new byte[received];
Array.Copy(_buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);

您有一个复制操作,它将收到的缓冲区复制到recBuf中,然后再复制一个以创建字符串。 您可以避免一个,您的性能将会提高。 但是cpu高的事实是正常的,因为即使转换为字符串也会使用cpu。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM