您的位置:首页 > 其它

一个封锁操作被对 WSACancelBlockingCall 的调用中断 ErrorCode=10004

2015-11-30 17:04 686 查看
转自:http://www.cnblogs.com/xiwang/archive/2012/10/25/2740114.html

C#中在使用UDPClient循环监听端口,在断开UPDClient的时候,使用try...catch捕获了异常,System.NET.Sockets.SocketException“一个封锁操作被对
WSACancelBlockingCall 的调用中断”,ErrorCode=10004。

      接收时的代码如下:

IPEndPoint ipendpoint = new IPEndPoint(IPAddress.Any, 0);
Thread thread = new Thread(() =>
{
while (!m_StopListen)
{
try
{
if (m_udpClient.Client == null) return;
byte[] bytes = m_udpClient.Receive(ref ipendpoint);

string str = Encoding.Default.GetString(bytes);
Console.WriteLine(string.Format("接收的数据是: {0},来自IP:{1} ,端口 : {2}", str, ipendpoint.Address.ToString(), ipendpoint.Port));

}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Thread.Sleep(100);
}
});
thread.IsBackground = true;
thread.Start();


 

       停止监听的代码:

this.m_StopListen = true;
m_udpClient.Close();
m_udpClient = null;


       解决办法:

      在开始调用UDPClient的Receive方法之前对UDPClient.Available属性进行判断,当Available属性大于0时才开始从缓冲区读取网络数据:

 

try
{
if (m_udpClient.Available <= 0) continue;
if (m_udpClient.Client == null) return;
byte[] bytes = m_udpClient.Receive(ref ipendpoint);

string str = Encoding.Default.GetString(bytes);
Console.WriteLine(string.Format("接收的数据是: {0},来自IP:{1} ,端口 : {2}", str, ipendpoint.Address.ToString(), ipendpoint.Port));

}


 

       原因:MSDN对Available的解释是:

      “Available 属性用于确定在网络缓冲区中排队等待读取的数据的量。 如果数据可用,可调用 Read 获取数据。 如果无数据可用,则 Available 属性返回
0。

    如果远程主机处于关机状态或关闭了连接,则 Available 属性将引发SocketException。如果远程主机处于关机状态或关闭了连接,则 Available 属性将引发SocketException”。

           也就是说,错误的原因在于,但调用Close后,线程恰好继续向网络缓冲区中读取数据,所以引发SocketException。

       (如果您知道, Windows Sockets Version 2 API(Windows 套接字第
2 版 API)错误代码文档 ,可以在那里下载到或者查看,烦请您留个言告诉我一声啊,谢谢了...)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: