• [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。

          接收时的代码如下:

    复制代码
    复制代码
    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。

         

    • 博客地址:http://www.cnblogs.com/wolf-sun/ 
      博客版权:如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。
  • 相关阅读:
    4.Linux的目录结构
    使用idea创建spring mvc项目图文教程
    传统的Servlet在spring boot中怎么实现的?
    springboot系列教程导学篇
    记录一次序列化引起的问题解决办法 查看已编译类序列化值
    springboot支付项目之springboot集成jpa
    springboot支付项目之日志配置
    设计模式之状态模式总结篇
    看了这个Java实习生入职测试题后,幸亏我不是实习生
    幂等性学习及接口的幂等性
  • 原文地址:https://www.cnblogs.com/asdyzh/p/9886054.html
Copyright © 2020-2023  润新知