首页 文章

C#:UDP侦听器线程

提问于
浏览
8

我想在我的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 回答

  • 9

    Listen 标记标记为volatile,因此可以在线程之间看到更改 .

    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

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

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

    try
                    {
                        broadcastSocket.ReceiveFrom(returnData, ref ep);
    
                        //...
                    }
                    catch (SocketException ex)
                    {
                        if (ex.ErrorCode == 10004)
                        {
                            break;
                        }
                    }
    

    为什么我必须使用

    socket.Shutdown(SocketShutdown.Both);
    

    之前

    socket.Close();
    

    Will .Close()也不会关闭套接字吗?

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

    问候user437899

相关问题