日期:2014-05-17  浏览次数:20989 次

异步读stream时遇到的一个奇怪的问题
先放两段代码:

        private void beginReadStatus()
        {
            receiveDataBuffer = null;
            receiveDataBuffer = new Byte[this.tcpclient.ReceiveBufferSize];
            tcpstream.BeginRead(receiveDataBuffer, 0, receiveDataBuffer.Length, new AsyncCallback(doReadStatus), tcpstream);
        }


        private void doReadStatus(IAsyncResult ar)
        {
             Stream stream = (Stream)ar.AsyncState;
             if (stream.CanRead)
             {
                 int dataSize = tcpstream.EndRead(ar);
                 ……(业务代码)
                 tcpstream.BeginRead(receiveDataBuffer, 0, receiveDataBuffer.Length, new AsyncCallback(doReadStatus), tcpstream);
             }
        }

这是个异步读的过程,在doReadStatus中stream.CanRead=true,但int dataSize = tcpstream.EndRead(ar)后dataSize=0,执行完业务代码后,再beginread,然后就又重复这个过程了,无限循环,导致cpu占用率很高。
不明白的是流(tcpstream)里数据大小为0,为什么还可以读?请真正明白的人帮忙解答下~

------解决方案--------------------
看来你是第一次用到Socket编程(上面其它回复的人也是如此),有Socket编程经验的人都知道,当读取时返回0个字节,就说明对方中断的TCP连接,也就是单方面的连接放弃,否则读取方法将会阻塞,不会返回。此时你只要判断接收到的数据是否为0个字节,是的话,你也将当前TCP连接关闭,中断当前会话(如果是一次性的会话,那就说明对方发送数据结束)。这里单方面的连接放弃也可能是网络异常导致,因此数据的完整性验证需要自己单独做,例如再发送的数据开头添加一个4字节数据(int的长度),指明后面的数据有多长,用来验证是否完整。