TCP服务器CPU占用率高
本文关键字:占用率 CPU 服务器 TCP | 更新日期: 2023-09-27 17:50:32
c# Visual Studio 2013
我正在做一个粗略的TCP服务器/客户端。它是这样工作的:
客户端向服务器发送消息,服务器向客户端发送"响应"。当我要在游戏中的多人游戏中使用这种数据传输时,我将在循环中使用它。但是,我进行了性能测试,因为当超过三个客户机连接时,我的TCP服务器使用了大量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。