当前位置:  开发笔记 > 编程语言 > 正文

TCP延迟确认的解决方法是什么?

如何解决《TCP延迟确认的解决方法是什么?》经验,为你挑选了1个好方法。

我发布了一个在线(基于网格)的视频游戏,它使用TCP协议来确保服务器 - 客户端网络拓扑中的可靠通信.我的游戏工作得相当好,但遭遇的延迟高于预期(类似的TCP游戏似乎在将延迟保持在最低限度方面做得更好).

在调查时,我发现运行Microsoft Windows(而不是Mac OS X客户端)的客户端的延迟仅意外高.此外,我发现如果Windows客户端设置TcpAckFrequency=1在注册表中并重新启动他们的计算机,他们的延迟就会变得正常.

看来我的网络设计没有考虑延迟确认:

不考虑延迟确认,Nagle算法和Winsock缓冲的交互的设计可以极大地影响性能.(http://support.microsoft.com/kb/214397)

但是,我发现几乎不可能在我的游戏(或任何游戏)中考虑延迟确认.根据MSDN,Microsoft TCP堆栈使用以下标准来决定何时在接收的数据包上发送一个ACK:

如果在延迟计时器到期(200ms)之前接收到第二数据包,则发送ACK.

如果在接收到第二数据包之前有数据要在与ACK相同的方向上发送并且延迟计时器到期,则ACK与数据段搭载并立即发送.

当延迟计时器到期(200ms)时,发送ACK.

(http://support.microsoft.com/kb/214397)

阅读本文,可以假设Microsoft TCP堆栈上延迟确认的解决方法如下:

    禁用Nagle算法(TCP_NODELAY).

    禁用套接字的发送缓冲区(SO_SNDBUF= 0),以便send可以预期调用发送数据包.

    在呼叫时send,如果不希望立即发送更多数据,则send再次使用将被接收器丢弃的单字节数据进行呼叫.

利用这种方法,接收器将在与先前数据分组大致相同的时间接收第二数据分组.因此,ACK应该立即从接收方发送到发送方(模拟TcpAckFrequency=1注册表中的内容).

但是,从我的测试来看,这个改进的延迟只有注册表编辑的一半左右.我错过了什么?


问:为什么不使用UDP?

答:我选择了TCP,因为我发送的每个数据包都需要到达(并按顺序); 如果丢失(或变得无序),则没有值得重传的数据包.只有当数据包可以被丢弃/无序时,UDP才能比TCP更快!



1> Mr. Smith..:

自Windows Vista起,TCP_NODELAY选项必须在调用之前设置connect,或者(在服务器上)在调用之前设置listen.如果你TCP_NODELAY在调用后设置connect,它实际上不会禁用Nagle算法,但GetSocketOption会说Nagle已被禁用!这一切似乎都没有记载,并且与该主题教授的许多教程/文章相矛盾.

随着Nagle实际禁用,TCP延迟确认不再导致延迟.

推荐阅读
李桂平2402851397
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有