C#:UDP侦听器线程

时间:2010-09-02 12:22:53

标签: multithreading sockets xna udp

我想在我的XNA-Networkgame中使用UDP-Sockets。 现在我正在尝试编写可靠的Listenetraread,但是有一些问题。

如果我使用socket.Receive它会等到一个数据包。这对我的Listenetraread很好。 我的线程有一个像这样的while循环:

while(Listen == true)
{
    socket.Receive(...);
}

但如果我将Listen-Flag交换为false(如果我想停止收听),它将停留在最后一个.Receive()。

然后我查看了Methodes .BeginReceive()。如果数据包到达,它将调用一个方法。 但是为了接收我必须使用的数据.EndReceive(),这就是我遇到的问题。我想仍然监听数据包,如果数据包到达,就不要停止监听。

所以我仍然使用带有“.Receive()”的阻止版本。我可以通过调用:Thread.abort()强制取消侦听线程,但这不好。

目前我测试数据是否可用:

while(Listen == true)
{
    if(socket.Available > 0)
    {
        socket.Receive(...);
    }
}

但我认为这不是最好的方法...如果在if子句之后不久,另一个线程正在调用socket.Receive(..),它将再次无意中卡住。 有没有办法取消.Receive(..)方法? 我试图设置超时,但如果.Receive超时,它将抛出异常...

我想要一个简单的udp-listening-thread,我可以优雅地停止。 :-) 在MSDN中,我没有找到一个侦听器示例,它正在侦听多个数据包。 如何处理其他程序员?

2 个答案:

答案 0 :(得分:9)

Listen标记标记为易失性,因此可以在线程之间看到更改。

public volatile bool Listen{get; set;}

处理线程中的相应异常:

Thread listener = new Thread(()=>
{
    while(Listen == true)
    {
        try
        {
            socket.Receive();
        }
        catch(ThreadInterruptException)
        {
            break; // exit the while loop
        }
        catch(SocketException)
        { 
            break; // exit the while loop
        }
    }
});
listener.IsBackground = true;
listener.Start();

在您将Listen标志切换为false的代码中,您要么关闭套接字,要么中断线程:

Listen = false;

socket.Shutdown(SocketShutdown.Both);
socket.Close();
//
// OR
//
listener.Interrupt();

答案 1 :(得分:1)

谢谢Lirik和Matt Davis。 它工作正常,但是可以使用Exceptions吗? 我已经知道只有在出现不良/意外情况时才应该抛出异常。 (停止阻止方法是:-))

我像这样处理了这个异常。我查找错误代码,然后打破循环。

                try
                {
                    broadcastSocket.ReceiveFrom(returnData, ref ep);

                    //...
                }
                catch (SocketException ex)
                {
                    if (ex.ErrorCode == 10004)
                    {
                        break;
                    }
                }

为什么我必须使用

socket.Shutdown(SocketShutdown.Both);

之前

socket.Close(); 

是否.Close()也不会关闭套接字?

如果我想再次使用套接字,是否有“Restart”-methode oder必须创建一个新的socketinstance?

问候 user437899