我的一个程序,服务器端每隔 0.1 秒发一帧数据,数据很小,100多字节,客户端使用 recv 函数接收,但为何接收到数据的时间间隔不平均,有的两帧间间隔达0.2秒,有的又只有0.02秒,这是什么原因造成的?如何解决?我估计可能是 TCP 协议内对缓冲区操作引起的,不知对否,该如何解决?谢谢!

解决方案 »

  1.   

    第一 neagle算法的原因  等待多个小的包和在一起发送 ,造成了延时
    第二 本身TCP IP网络的数据传输就具有不确定性。有多条通路时 很可能数据走的路线是不一样的
      

  2.   

    Winsock的Nagle算法将降低小数据报的发送速度,而系统默认是使用Nagle算法,使用 int setsockopt(   SOCKET s,                   int level,                   int optname,                const char FAR *optval,    int optlen                );函数关闭它 例子: SOCKET sConnect; sConnect=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); int bNodelay = 1; int err; err = setsockopt(         sConnect,         IPPROTO_TCP,         TCP_NODELAY,         (char *)&bNodelay,         sizoeof(bNodelay));//不采用延时算法 if (err != NO_ERROR) TRACE ("setsockopt failed for some reason ");;   
      

  3.   

    谢谢您,我客户端是采用将recv放在一个多线程的循环中以阻塞方式接收的,一旦接收到一帧数据即采用 Sendmessage 发送一个消息,对数据进行处理。不同的通路不大可能,就一个客户端,一个服务器端通过 Hub 连接起来出现了间隔不等的情况
      

  4.   

    各位已经说的很清楚了,我想总结一下:
    1.网络的时延是存在的,所以数据到达的时间和数据产生端的时间间隔是不可能绝对保持一致的。
    2.Nagle算法对小包的聚集也会产生延迟,如果你使用TCP协议的化。参考:
    http://blog.csdn.net/windcsn/archive/2005/07/18/428166.aspx
    3.你的应该程序一定要设计成这种时间间隔的方式吗?尽量避免这个方式
    4.如果非要设计如此,请考虑在接收端自行处理,而不能根据网络事件。但这样也不是很准确,且最后得到的结果可能和你想要的结果不太一样。
      

  5.   

    latency= 传输延迟+接收延迟
    我想最大的原因应该是在接收延迟,可以你接受第N个包在对其处理之前,第N+1个包已经到达客户机了,并被网卡驱动缓冲起来了。所有,很正常。建议将服务器端每隔 0.1 秒发一帧数据设置为
    服务器端每隔 5~10 秒发一帧数据,应该就差不多是一样的啦。
      

  6.   

    不同意楼上的观点:
    1.对于网络应用程序来说,数据在网络上的传说时间绝对大于数据在接收端的接收时间.SOCKET吸收数据是很快的。如果接收端应用程序不是处理大量的事情,对到达的数据很能很快的吸收。
    2.Nagle算法有200ms(0.2s)的延迟,当然对于0.1s的时间间隔是不理想的;明显你的数据很小,肯定被Nagle算法挡在那里了。
    建议:
    1.修改发送间隔时间(至少>0.2s),如果一定要同步间隔,但这并不能保证一定可以同步
    2.接收端采用多线程,保证数据接收不被你的应用程序运算组塞住,而让你的数据在SOCKET没有取而可能导致SOCKET区被FILL满,再导致发送端不能发送。
      

  7.   

    需要考虑网络中的传输延时,还有处理延时等
    你用的阻塞方式,也可能导致时间的等待
    还有Nagle算法对于包的处理,需要等待另一端的返回,才继续发送...
      

  8.   

    影响的东西很多阿,网络发送的系统优先度不是很高,如果在发送时系统有某些高优先的线程在执行可能会影响,网络硬件也会影响啊,如果是使用hub,万一发生了端口冲突会影响发送时间。等等
      

  9.   

    把Socket的缓冲区设成0就OK了,但是没有人用这么变态的方法.
      

  10.   

    我的程序是这样的,一个服务器端带五个客户端,服务器端上有一个计算模型,三个客户端为该计算模型提供输入数据或改变输入数据,两个客户端从服务器端获取数据并以图形化的方式显示,其中一个是以GDI画的,另外一个是用OpenGL画的,麻烦就麻烦在这两个客户端上,特别是OpenGL的那个。因为服务器端模型的计算间隔直接影响到前后两帧输出数据的步长,如果客户端接收到的数据间隔不一(不要求完全一致,但不能差太多,向开始那样的0.2 和 0.02 就不行)那么在客户端图形绘制时就会出现跳动现象。经过诸位指教,采用关闭Nagle算法的方法能够很好的满足程序运行的要求,目前,针对opengl 那个客户端采取50帧的的速率,其余客户端采用10帧的数率,程序可以取得比较满意的运行效果。
    感谢诸位的帮助和指教!