none
关于读取网络数据流 RRS feed

  • 问题

  • 在读取网络数据流(如ConnectSteam或NetworkStream)时,调用同步或异步读方法,都有一个size参数,msdn解释说“The number of bytes to read from the XXX”,还有返回值,msdn上说“The number of bytes read from the XXX”,Remark 中也有如下说明“This method reads data into the buffer parameter and returns the number of bytes successfully read. If no data is available for reading, the Read method returns 0. The Read operation reads as much data as is available, up to the number of bytes specified by the size parameter 。。。。。。”
        按我的理解,size参数时读取流时期望得到的数据大小,而返回值才是流真正返回的数据的大小。网上的好多网络程序代码对读取数据时也是根据返回值来判断读取到的字节数的。
        现在问题是,我见到应用中的访问网络流的代码,每次读取时,并不关心返回值,而是把size参数的值做为本次读取到的字节的大小。而这样判断是在一个比较大的生产项目中运行,并且没有因此出过问题。 我想问下,在读取网络流的时候,传入的size参数就一定是返回的字节的大小么(不包括网络断开返回0字节的情况),如果不是,那么在以size值做为返回字节大小的情况下,都在什么情况下会发生问题?是不是和服务端ip数据报的大小有关系?
        希望大家能帮忙解释下,我觉得把size参数做为返回数据大小不正确,应该是根据ReturnValue判断的,但在事实面前却讲不出道理来。

    2009年12月18日 5:27

答案

  • 用NetworkStream的返回值来判断读取到的数据大小是正确的,

    但是如你所述,有时从size参数读取大小也正确,这就要看情况了
    如果你的参数是这样建立的,byte大小为文件的长度
    byte[]  byte=new byte[fs.lenth];
    直接读取就没问题

    如果你的byte是这样建立的
    byte[]  byte=new byte[1024];
    读取就能出现问题

    努力+方法=成功
    • 已标记为答案 YiChun Chen 2009年12月21日 11:12
    2009年12月18日 6:35
  • 按照我个人的理解 size是希望从缓存中读取的字节数 返回的是实际读取的 比如缓存中的字节长度小于这个size 就返回实际的size
    由于这个size一般不会太大 所以在数据流很大的情况下 这个方法返回的就等于size 但是当确实存在刚才说的这种情况 无法也不会太大最多size-1 个字节 所以并没有影响

    另外读取的方法返回的是实际读取到的字节数 并不是size 这个返回值是<=size 的
    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈!My blog~~~
    • 已标记为答案 YiChun Chen 2009年12月21日 11:12
    2009年12月18日 6:58
    版主

全部回复

  • 用NetworkStream的返回值来判断读取到的数据大小是正确的,

    但是如你所述,有时从size参数读取大小也正确,这就要看情况了
    如果你的参数是这样建立的,byte大小为文件的长度
    byte[]  byte=new byte[fs.lenth];
    直接读取就没问题

    如果你的byte是这样建立的
    byte[]  byte=new byte[1024];
    读取就能出现问题

    努力+方法=成功
    • 已标记为答案 YiChun Chen 2009年12月21日 11:12
    2009年12月18日 6:35
  • 按照我个人的理解 size是希望从缓存中读取的字节数 返回的是实际读取的 比如缓存中的字节长度小于这个size 就返回实际的size
    由于这个size一般不会太大 所以在数据流很大的情况下 这个方法返回的就等于size 但是当确实存在刚才说的这种情况 无法也不会太大最多size-1 个字节 所以并没有影响

    另外读取的方法返回的是实际读取到的字节数 并不是size 这个返回值是<=size 的
    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈!My blog~~~
    • 已标记为答案 YiChun Chen 2009年12月21日 11:12
    2009年12月18日 6:58
    版主
  • 多谢开心和Raymond Tang2位解答,
    to 开心:对于网络数据流,一般是不可以Seek的,这个length一般拿不到。还有,即使通过其它途径拿到(如Content-Length头),那么在传输比较大的数据时,一次性分配一个大的内存块来读取数据,恐怕也不是很好。
    to Raymond Tang: 我自己也一直是这样理解的。

    在一次异步读取中,按照ReturnValue来判断实际返回的字节数会比按size来判断的情况复杂很多,即使是同步读取的情况下,这种判断也会比拿size做为返回数据大小的情况要复杂一些。
    而在使用这2种判断方法都不出问题的前提下,按照ReturnValue来判断实际返回的字节数无疑会被认为是多此一举,且其可读性也比后一种方法低。

    我对别人的把size做为实际返回的字节数的写法不放心,但又找不出那种写法在什么情况下会出问题。
    我见过一个项目,在从NetworkStream读取数据时,就是认为每次读进buffer的数据大小就是指定的size的大小,并且这个项目可能运行了不下一年,那里也没发生过问题,这实在是和我以前的理解
    不相符。 那么是不是在特定的环境下,比如,size的大小在某个范围内,或者网络通信的繁忙程度在某个范围内等情况下,把size做为从流中实际读取到的字节数和把returnValue用作实际读取到的字节数
    所得到的结果是等同的。

    再次感谢2位

    2009年12月18日 7:40
  • 没有人再解释得更详细一些么?
    这里有时我感觉总是知其然,却不知其所以然。
    再等一天,明天结贴
    2009年12月20日 8:59
  • 为什么我接收较大的流的时候就会不行呢?

    我会出现

    无法从传输连接中读取数据: 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败

    2010年6月9日 8:32