C# (显然)优雅地关闭UDPClient会使套接字阻塞
尽管下面的代码显然关闭了UDP套接字,但它仍然挂起,无法重新连接到相同的地址/端口 以下是我使用的类变量:C# (显然)优雅地关闭UDPClient会使套接字阻塞,c#,.net,multithreading,sockets,udpclient,C#,.net,Multithreading,Sockets,Udpclient,尽管下面的代码显然关闭了UDP套接字,但它仍然挂起,无法重新连接到相同的地址/端口 以下是我使用的类变量: Thread t_listener; List<string> XSensAvailablePorts; private volatile bool stopT_listener = false; volatile UdpClient listener; IPEndPoint groupEP; 方法如下(我在Receiv
Thread t_listener;
List<string> XSensAvailablePorts;
private volatile bool stopT_listener = false;
volatile UdpClient listener;
IPEndPoint groupEP;
方法如下(我在Receive
上使用一个超时,以便在套接字上没有发送任何内容并且发出Stop
时不使其被阻止):
尽管在debug中检查套接字是否已关闭,但如果我尝试连接到同一端口,我无法这样做,因为它会引发
SocketException
,表示通常只允许使用一个端口/地址。我将您提供的代码以简单的形式放入运行它的程序中,然后。。。我不能直接重现你的问题。虽然我没有向客户端发送任何数据,但据我所知,它不应该改变任何东西,因为它是UDP,我们正在调查(重新)打开套接字,而不是传输数据
单击开始/停止按钮时,插座始终正确打开和关闭,重新打开可按预期工作。
对我来说,强制执行您提到的SocketException的唯一方法是引入一些明显的套接字逻辑误用:
你能检查一下端口在你关闭后是否仍然打开吗?您可以使用
netstat-an
,或优秀的ProcessExplorer工具。您还可以检查t_侦听器线程是否正确终止(标准任务管理器或ProcessExplorer可以帮助您)。将侦听器对象设置为NULL,以便释放资源,这也会释放连接。我也有同样的问题,问题出在UDPClient.Receive(),她使插座处于已使用状态,即使您呼叫Close/shutdown/`
try{ // receive loop}
catch{}
finally {
UDP_Listner.Close();
UDP_Listner = null;
}
编辑:
t_listener = new Thread(UDPListener);//replace by :
t_listener = new Thread(new ThreadStart(UDPListener));
`
为了安全地关闭socket和thread()我也有同样的问题,我是最安全的程序员,我总是很好地关闭所有东西。但是我发现.net类关闭套接字的速度不够快。因为如果我走得慢,它不会发生,但如果我打开和关闭(完全清理)并快速打开它,我会得到同样的错误。尤其是当用户希望再次运行相同的代码并再次打开端口时。可能是一个旧答案,但在您试图找到一个可用的端口时,失败了,我会在下一次迭代之前处理您测试的侦听器实例
try
{
currPort = Int32.Parse(XSensAvailablePorts[currAttempt]);
listener = new UdpClient(currPort);
successfullAttempt = true;
}
catch (Exception e)
{
currAttempt++;
if(listener != null)
{
listener.Close();
}
}
我认为绑定或重用可以解决这个问题(即使套接字还没有关闭,它也可以重用,并且不会抛出错误) 示例代码:
udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, p));
当您单击按钮时,可能是什么
listener.Client
为null
?您将不会调用listener.Close()
。@Sinatr我签入了debug,但事实并非如此。Close()应该完全处理该对象。这一定是其他原因,比如没有正确地关闭套接字(可能是由于没有处理某些异常,只是跳过了这些异常)。我不知道,因为我刚刚使用了.BeginReceive异步方法来处理数据;pI无法访问我与之通信的硬件/软件(正如您可能从我访问XSens body suit用于身体跟踪的套接字流的变量名称中了解到的),但我将在下周进行检查。我对这个组件的数据流有太多问题,我怀疑这可能是服务器的错误,有些东西出了问题。我没有将对象设置为null并等待GC释放资源,而是使用Close()/Dispose()强制释放资源,但也没有起作用。这是回答还是评论?
t_listener = new Thread(UDPListener);//replace by :
t_listener = new Thread(new ThreadStart(UDPListener));
try
{
currPort = Int32.Parse(XSensAvailablePorts[currAttempt]);
listener = new UdpClient(currPort);
successfullAttempt = true;
}
catch (Exception e)
{
currAttempt++;
if(listener != null)
{
listener.Close();
}
}
udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, p));