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

在读取网络流之前,先添加一条判断语句:

                    //client.Available属性进行判断,当Available属性大于0时才开始从缓冲区读取网络数据
                    if (client.Available <= 0) continue;

MSDN对Available的解释是:

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

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

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

今天搜索度娘一下午都没找到答案,最终找到了http://www.cnblogs.com/xiwang/archive/2012/10/25/2740114.html得到了启发

 

但我的代码是引发了IOException异常
另附接收网络流部分完整代码:

        /// <summary>
        /// 接收服务器发送的信息
        /// </summary>
        private void ReceiveData()
        {
            while (isDisconnect == false)
            {
                //保存接收的命令字符串
                string receiveString = null;
                //解析命令用
                //每条命令均带有一个参数,值为true或false,表示是否有紧跟的字节数组
                string[] splitString = null;
                byte[] receiveBytes = null;
                try
                {
                    //client.Available属性进行判断,当Available属性大于0时才开始从缓冲区读取网络数据
                    if (client.Available <= 0) continue;
//从网络流中读出命令字符串
                    //此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串
                    receiveString = br.ReadString();
                    splitString = receiveString.Split('|');
                    if (splitString[1] == "true")
                    {
                        //先从网络流中读出32位的长度前缀
                        int bytesLength = br.ReadInt32();
                        //然后读出指定长度的内容保存到字节数组中
                        receiveBytes = br.ReadBytes(bytesLength);
                    }

                }
                catch (Exception ex)
                {
                    //底层套接字不存在时会出现异常,将错误信息写入Log
                    new ExLog().WriteLog("ReceiveData", ex.Message);
                }
                if (receiveString == null)
                {
                    if (isDisconnect == false)
                    {
                        //如果与服务器断开代码Application.Exit();
                        MessageBox.Show("与服务器的连接中断。\n\n请检查网络,并重新开启本程序。", "系统错误", MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning);
                    }
                    break;
                }
                //getMessage("收到命令:" + receiveString);
                //if (receiveBytes != null)
                //{
                //    getMessage(string.Format("收到加密内容:{0}", Encoding.Default.GetString(receiveBytes)));
                //}
            }
            //Application.Exit();
        }

 

posted on 2012-12-30 20:34  binbr  阅读(2512)  评论(0)    收藏  举报

导航