【发布时间】:2014-02-23 16:41:11
【问题描述】:
我几乎遍及 Google,甚至在 Stack Overflow 上都查看过,但我似乎找不到我正在寻找的解决方案。我正在测试我的编程技能,使用 MonoGame for C# 重新制作 Pong,我正在尝试使用 UDP 客户端和 UDP 服务器制作这个多人游戏。我将采用“完美的客户端-服务器模型”的想法,服务器处理所有计算,而游戏客户端只是从服务器接收数据并将其显示在屏幕上。不幸的是,我在处理 UDP 服务器编程时遇到过问题。我有一个循环,我在其中接收数据报,然后开始监听另一个。我使用异步调用,因为在我看来,这对客户端和服务器最有效。 Main 代码如下所示:(我将删除不会影响 CPU 的部分,仅显示网络。)
static void Main()
{
//Initialize
Console.Title = "Pong Server";
Console.WriteLine("Pong Server");
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//Bind socket
EndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 25565);
Console.WriteLine("Binding to port 25565");
serverSocket.Bind(localEndPoint);
//Listen
Console.WriteLine("Listening on {0}.", localEndPoint);
//Prepare EndPoints
EndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0);
//Recive Data...
rcvPacket = new byte[Data.Size];
serverSocket.BeginReceiveFrom(rcvPacket, 0, Data.Size, SocketFlags.None, ref clientEndPoint, new AsyncCallback(Receive), null);
}
然后在Receive(IAsyncResult ar)方法中:
static void Receive(IAsyncResult ar)
{
//Prepare EndPoints
EndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0);
//End
int PacketSize = serverSocket.EndReceiveFrom(ar, ref clientEndPoint);
//<Handle Packet Code Here>
//Receive Loop
rcvPacket = new byte[Data.Size];
serverSocket.BeginReceiveFrom(rcvPacket, 0, Data.Size, SocketFlags.None, ref clientEndPoint, new AsyncCallback(Receive), null);
}
这段代码的样子是它会等到收到一个数据包,然后再监听另一个数据包,这将停止这个“监听器”线程,是异步的。无论如何,感谢您阅读我的问题,希望我能深入了解这一点。
哦,顺便说一下,这是我的 4 个核心中的一个被最大化的图像。 (是的,我目前正在调试它。)
【问题讨论】:
-
当在 Receive(IAsyncResult ar) 方法中接收到数据包时,它会侦听另一个数据包。在两个代码sn-ps的底部,可以看到监听器,第二个sn-p就是“循环”
-
我编辑了原始帖子,以便更容易看到循环。 Receive(ar) 从 Main() 方法(命令行应用程序)调用,并在 Receive(ar) 结束时调用Receive(ar) 方法,继续监听数据包。
-
在调试器中暂停它并查看调用堆栈,看看它在忙什么。
-
Data.Size的大小是多少?如果是0,您将得到您描述的行为。 -
它可能不是空的,但如果没有 sleep 或 yield 它肯定会使用 100% 的 CPU 内核(如果不涉及 IO 请求)。将该代码添加到您的问题中,我们可以帮助您解决它。
标签: c# performance sockets udp cpu-usage