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

摘要:
接收代码如下:IPEndPointipendpoint=newIPEndPoint;Threadhread=newThread(()=˃{while(!也就是说,错误的原因是,在调用Close之后,线程只是继续将数据读入网络缓冲区,因此会触发SocketException。如果您认为这篇文章对您有帮助,为什么不呢?如果您有更好的建议,为什么不留言讨论并一起取得进展?再次感谢您耐心阅读这篇文章。

原文地址: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/ 
    博客版权:如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。

免责声明:文章转载自《[Socket网络编程]一个封锁操作被对 WSACancelBlockingCall 的调用中断。》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇nginx常用功能和配置BTC_ETH_USDT_自动充提币API接口,钱包对接交易所教程!下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python并发编程:阻塞IO

阻塞IO(blocking  IO) 在Linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样:   当用户进程调用了recvfrom这个系统调用,kernel就开始了IO的第一个阶段:准备数据。对于network io来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的udp包),这个时候kernel...

使用select实现非阻塞socket | dbafree首页

使用select实现非阻塞socket | dbafree首页 在linux,perl,python上都存在select系统调用。下面这两个python程序,可以用来学习和调试select操作。 参考至:http://blog.chinaunix.net/space.php?uid=199788&do=blog&id=99434 1.服务...

socket,websocket,socketio之间的关系

socket:Socket是传输控制层协议,Socket其实并不是一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。可以方便的使用TCP和UDP协议。 websocket:websocket是基于TCP传输层协议实现的一种标准协议。用于在客户端和服务端双向传输数据。 socketio:socket.io是将W...

基于workerman的实时推送(摒弃ajax轮询)

先扯些这些内容: TCP/IP TCP/IP是个协议组,可分为三个层次:网络层、传输层和应用层。 在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。 在传输层中有TCP协议与UDP协议。 在应用层有: TCP包括FTP、HTTP、TELNET、SMTP等协议 UDP包括DNS、TFTP等协议 短连接 连接->传输数据->...

TCP协议粘包问题详解

TCP协议粘包问题详解前言   在本章节中,我们将探讨TCP协议基于流式传输的最大一个问题,即粘包问题。本章主要介绍TCP粘包的原理与其三种解决粘包的方案。并且还会介绍为什么UDP协议不会产生粘包。   基于TCP协议的socket实现远程命令输入   我们准备做一个可以在Client端远程执行Server端shell命令并拿到其执行结果的程序,而涉及...

Socket与Http方式解析发送xml消息封装中间件jar包

  最近项目代码中太多重复的编写Document,不同的接口需要不同的模板,于是重写提取公共部分打成jar包,方便各个系统统一使用~   提取结构:    Http连接方式: import java.nio.charset.Charset; import java.util.Arrays; import java.util.List; import...