[Socket网络编程]一个*操作被对 WSACancelBlockingCall 的调用中断。

原文地址:http://www.cnblogs.com/xiwang/archive/2012/10/25/2740114.html记录在此,方便查阅。

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

      接收时的代码如下:

[Socket网络编程]一个*操作被对 WSACancelBlockingCall 的调用中断。
[Socket网络编程]一个*操作被对 WSACancelBlockingCall 的调用中断。
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();
[Socket网络编程]一个*操作被对 WSACancelBlockingCall 的调用中断。
[Socket网络编程]一个*操作被对 WSACancelBlockingCall 的调用中断。

 

       停止监听的代码:

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

       解决办法:

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

 

[Socket网络编程]一个*操作被对 WSACancelBlockingCall 的调用中断。
[Socket网络编程]一个*操作被对 WSACancelBlockingCall 的调用中断。
                            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));

                            }
[Socket网络编程]一个*操作被对 WSACancelBlockingCall 的调用中断。
[Socket网络编程]一个*操作被对 WSACancelBlockingCall 的调用中断。

 

       原因:MSDN对Available的解释是:

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

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

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

     

博客地址: http://www.cnblogs.com/wolf-sun/
博客版权: 本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。
如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!
再次感谢您耐心的读完本篇文章。

转载:http://www.cnblogs.com/wolf-sun/p/3366353.html
上一篇:【Groovy】集合遍历 ( 操作符重载 | 集合中的 “ << “ 操作符重载 | 使用集合中的 “ << “ 操作符添加一个元素 | 使用集合中的 “ << “ 操作符添加一个集合 )


下一篇:【Groovy】集合声明与访问 ( 使用 [] 创建 ArrayList 和 LinkedList 集合 | 集合赋初值 | 使用下标访问集合 | 使用 IntRange 作为下标访问集合 )(二)