none
NetWorkStream能确保传输的可靠性吗? RRS feed

  • 问题

  • 如题:
          我用NetWorkStream类写了一个简单的C/S程序,由多个Client端定时发送消息给Server端,并将消息存入文本.发现大部分时间都能正常运行,但是偶尔会有数据不正确的情况发生,
          客户端使用NetworkStream.write同步发送,而服务端使用NetworkStream.BeginRead接收信息receivebuffer是默认的8196.分析了一下出错时候的情况,都是服务端接收的数据不正确,信息大多超过8196字节,出错的时候只是前面一部分大概1000-2000个字节跟client端的数据不一致,后面的基本上都一致.
          现在有点迷惑,到底是我程序本身的问题还是NetWorkStream类本身有可能在网络波动的时候造成数据错乱? 
          如果是后者的话我现在要做的只是出错重传机制,如果是前者的话还得仔细研究源代码,但是现在搞了很久有点迷糊了.
          补充一下,程序使用的是TCP协议.我的程序95%以上的时间都正常运行,请有经验的大家给点建议.并且信息出错的时候无论在Client还是Server都没有抛出异常.
    2009年12月12日 15:31

答案

  • 你好!
         一般还是你的程序处理不当导致的,每个类都有他自己的特点,如果使用不当就容易出现问题了!
    周雪峰
    • 已标记为答案 picat 2009年12月13日 7:29
    2009年12月13日 2:42
    版主

全部回复

  • 你好!
         一般还是你的程序处理不当导致的,每个类都有他自己的特点,如果使用不当就容易出现问题了!
    周雪峰
    • 已标记为答案 picat 2009年12月13日 7:29
    2009年12月13日 2:42
    版主
  •     确实是代码处理不当引起的,终于找到原因了,哈哈.
        这里也给大家介绍点经验,是这段时间以来,特别是为了调试上面提到的错误总结出来的,不对之处还望指出.
        由于客户端使用的是同步的NetworkStream.Write方法,同时客户端的SendBuffer是默认的8192,而客户端发送消息的大小又超过了8192字节,MSDN上对SendBuffer有这样一段话:   

    网络缓冲区应至少与应用程序缓冲区同样大小,这样才能确保在一次操作中就能存储和发送所需的数据。使用 SendBufferSize 属性设置此大小。如果应用程序要发送批量数据,需为 Write 方法提供足够大的应用程序缓冲区。

    如果网络缓冲区小于提供给 Write 方法的数据量,则对 Write 方法的每次调用都将多次执行网络发送操作。通过确保网络缓冲区至少与应用程序缓冲区同样大小,可获得更大的数据吞吐量。

        我并没有设置SendBuffer的大小,也没有根据默认大小8192来将客户端消息分段发送,而是直接NetworkStream.Write(msgdata,0,msgdata.length).对上面的话则对 Write 方法的每次调用都将多次执行网络发送操作 想当然的以为会以每次8192字节拆分发送,结果最终发现,在大部分情况下确实是每次8192字节,但是约有10%不到的情况下并不是8192.这个可能跟当时的网络状况有关系.而这也正是造成我本贴提到的错误的原因.其中的具体机制还有待知道的朋友告诉大家.
       
        最后还有两个疑问:
        1:对于 如果网络缓冲区小于提供给 Write 方法的数据量,则对 Write 方法的每次调用都将多次执行网络发送操作。通过确保网络缓冲区至少与应用程序缓冲区同样大小,可获得更大的数据吞吐量。 这句话该怎么理解?该方法本身会对大于SendBuffer的时候分次执行,那么还有没有必要在程序中人为根据SendBuffer的大小来分次传送? 它说的可获得更大的数据吞吐量。该怎么理解?

       2:如果对于大于SendBuffer的消息每次人为的按SendBuffer大小分段循环传送,是不是在接收端接收到的肯定是SendBuffer大小?还是也会根据网络状况将SendBuffer分次传送或者一次传送?目前我的解决方法是Client段不变,Server端每次接收都会事先确认发送字段的大小再Redim给接收变量数组.如果是前者,那么我只要在Client段指定SendBuffer,而Server端也指定相同的ReceiveBuffer就可以了,不用每次都判断这么麻烦.

       

    2009年12月13日 7:30
  • 感谢picat分享你的经验啊!
    周雪峰
    2009年12月13日 8:45
    版主