UDPClient.Receive()阻止任何代码运行

时间:2015-02-25 15:57:14

标签: c# xna udpclient

我正在尝试使用XNA Framework创建一个简单的游戏。我开始在局域网上实现多人游戏。一切都进展顺利,但现在我遇到了UDPClient.Receive的问题。

当服务器运行时,它应该在不同的端口上有两个侦听器(使用UDPClient.Receive)。一个听众正在等待想要加入游戏并相应地做出响应的人的任何传入连接请求。另一个听取玩家位置的不断更新,以便让所有玩家的视图保持同步。问题是我不知道如何在第一个监听器中编码。

当连接请求的侦听器启动时,所有代码都会冻结,并且在侦听器收到某些内容之前它不会启动。我如何编码它以便它只是在后台运行?

以下是我的连接侦听器代码:

public class Connect
{
    public static void WaitForConnections()
    {
        UdpClient udpc2 = new UdpClient(2054);
        IPEndPoint ep = null;

        Random rnd = new Random();

        Console.WriteLine("Waiting for connections...");
        byte[] joinrequest = udpc2.Receive(ref ep);
        if (Encoding.ASCII.GetString(joinrequest) == "join")
        {
            Console.WriteLine("Attempting to join");
            if (Server.ConnectedPlayers.Count < Server.MaxPlayers)
            {
                byte[] newShooter = DataControls.ClassToByteArray(new ShooterObject(Server.ConnectedPlayers.Count + 1, new Vector2(((Server.ConnectedPlayers.Count + 1) * 100) + 22, 70), new byte[3] { (byte)rnd.Next(255), (byte)rnd.Next(255), (byte)rnd.Next(255) }));
                udpc2.Send(newShooter, newShooter.Length, ep);
                Console.WriteLine("Joined successfully");
            }
            else
            {
                byte[] error = Encoding.ASCII.GetBytes("full");
                udpc2.Send(error, error.Length, ep);
                Console.WriteLine("Too many players");
            }
        }
    }
}

1 个答案:

答案 0 :(得分:-1)

您需要使用后台工作线程或等效线程(通常查看Task和线程),但是为了帮助您完成基本的完整示例:

using System;
using System.ComponentModel;
using System.Threading;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main()
        {
            // Create our listener and start listening...
            var sammpleListener = new SampleListener();
            sammpleListener.StartListening();

            // Run forever...
            Console.WriteLine("Waiting for players to join...");
            Console.WriteLine("Press Ctrl+C to stop!");
            for (var counter = 1;; counter++)
            {
                Console.WriteLine("Main thread working: {0}...", counter);
                Thread.Sleep(200);
            }
        }

        internal class SampleListener
        {
            private readonly BackgroundWorker _udpWaitForPlayer;

            public SampleListener()
            {
                _udpWaitForPlayer = new BackgroundWorker();
                _udpWaitForPlayer.DoWork += _udpWaitForPlayer_DoWork;
            }

            public void StartListening()
            {
                _udpWaitForPlayer.RunWorkerAsync();
            }

            private void _udpWaitForPlayer_DoWork(object sender, DoWorkEventArgs e)
            {
                const int junkSample = 10;
                for (var i = 1; i <= junkSample; i++)
                {
                    // Notice how this doesn't make the main thread sleep / hang...
                    Console.WriteLine("Background worker working: {0} of {1}...", i, junkSample);
                    Thread.Sleep(1000);
                }
                Console.WriteLine("Background worker: Finished!");
            }
        }
    }
}