Sockets 如何加快缓慢/滞后的Windows Phone 7(WP7)TCP套接字传输?

Sockets 如何加快缓慢/滞后的Windows Phone 7(WP7)TCP套接字传输?,sockets,windows-phone-7,windows-phone-7.1,latency,system.net,Sockets,Windows Phone 7,Windows Phone 7.1,Latency,System.net,最近,我开始使用WP7的Mango发行版中引入的System.Net.Sockets类,并一直很喜欢它,但我注意到在调试模式下传输数据的延迟与在手机上正常运行的延迟之间存在差异 我正在编写一个“远程控制”应用程序,当用户点击应用程序中的按钮时,它通过Wifi将一个字节传输到我局域网上的本地服务器。因此,感知到的应用程序响应性/及时性对于良好的用户体验非常重要 当手机通过USB线连接到我的电脑,并在调试模式下运行应用程序时,TCP连接似乎能像用户点击按钮一样快速传输数据包 在手机与PC断开连接的情

最近,我开始使用WP7的Mango发行版中引入的System.Net.Sockets类,并一直很喜欢它,但我注意到在调试模式下传输数据的延迟与在手机上正常运行的延迟之间存在差异

我正在编写一个“远程控制”应用程序,当用户点击应用程序中的按钮时,它通过Wifi将一个字节传输到我局域网上的本地服务器。因此,感知到的应用程序响应性/及时性对于良好的用户体验非常重要

当手机通过USB线连接到我的电脑,并在调试模式下运行应用程序时,TCP连接似乎能像用户点击按钮一样快速传输数据包

在手机与PC断开连接的情况下,用户最多可以点击7个按钮(因此,在发送所有7个字节之前,情况7使用1个字节的有效负载“发送”命令)。如果用户点击一个按钮并在点击之间稍等,则可能会有1秒的延迟

我已尝试将Socket.NoDelay设置为True和False,但似乎没有任何区别。

为了了解发生了什么,我使用了数据包嗅探器来查看流量

  • 当手机通过USB连接到PC(使用Wifi连接)时,每个字节都在其自己的数据包中,间隔约200ms

  • 当手机使用自己的Wifi连接(与USB断开连接)运行时,字节仍有自己的数据包,但它们都以4或5个数据包的形式分组在一起,每组距离下一组约1000毫秒

顺便说一句,从我的笔记本电脑上测量,我的Wifi网络到服务器的Ping时间很低,只有2ms


我意识到将“发送”缓冲在一起可能会让手机节省能源,但有没有办法禁用此“延迟”应用程序的响应比省电更重要。

很可能这不是软件问题。如果手机使用WiFi,延迟可能超过70毫秒(取决于服务器所在位置、带宽大小、繁忙程度、对AP的干扰以及与AP的距离),但大部分延迟仅限于WiFi。使用GMS、CDMA、LTE或手机用于蜂窝数据的任何技术甚至更慢。除非你站在一个手机发射塔下面,否则我无法想象你在一台手机上的速度会远低于110毫秒。

这确实是一个有趣的问题!我将投入2美分,但请注意,我不是WP7上System.Net.Sockets的专家

首先,在调试器中进行的性能测试应该被忽略。原因是,记录堆栈跟踪的额外开销总是会降低应用程序的速度,无论是操作系统/语言/IDE。应在发布模式下分析应用程序的性能,并断开与调试器的连接。在你的情况下,它实际上更慢!好吧,让我们试着优化一下

如果您怀疑数据包正在被缓冲(这是一个合理的假设),您是否尝试发送更大的数据包?尝试线性增加数据包大小并测量延迟。你能在设备上用代码编写一个简单的微分析器吗?例如:使用DateTime.Now或Stopwatch类来记录延迟与数据包大小的关系。绘制这张图可能会让你对你的理论是否正确有很好的了解。如果您发现10字节(甚至100字节)的数据包立即被发送,那么我建议您只需在每次传输中推送更多数据。这是一个蹩脚的黑客我知道,但如果它没有打破

最后你说你正在使用TCP。你能试试吗?TCP不是为实时通信而设计的,而是为精确通信而设计的。相比之下,UDP没有错误检查,您不能保证交付,但您可以期望从中获得更快(更轻量、更低延迟)的性能。Skype和在线游戏等网络是基于UDP而非TCP构建的。如果您确实需要接收确认,您可以始终在UDP上构建自己的微协议,使用自己的微协议进行错误检查和验证

此类协议确实存在,请参阅中讨论的。关于RUDP有一个基于Java的实现,但我确信有些部分可以移植到C。当然,第一步是测试UDP是否真的有用


找到了讨论此问题的前一个问题。也许是Wp7问题?

仍然有兴趣看看增加数据包大小或切换到UDP是否有效


好吧,这两个建议都不起作用。我找到了对Nagle算法的描述,该算法按照您描述的方式对数据包进行分组。设置NoDelay应该是有帮助的,但正如你所说的,没有

还有。请参阅前面的问题,其中Keepalive和NoDelay被设置为打开/关闭以手动刷新队列。他的证据是轶事,但值得一试。你能试一试并编辑你的问题来发布更多最新的结果吗


听起来您的读/写操作是缓冲的。您可以尝试将套接字上的NoTror属性设置为true,也可以考虑修剪发送和接收缓冲区大小。响应能力的降低可能是由于没有足够的wifi流量造成的,我不确定是否可以选择调整MTU,但减少MTU可能会提高响应时间

所有这些都是低带宽解决方案的唯一选项,如果您打算向任一方向铲取兆字节的数据,您将需要wifi上更大的缓冲区,足以补偿传输延迟,通常在32K-256K范围内

    var socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    {
        NoDelay = true,
        SendBufferSize = 3,
        ReceiveBufferSize = 3,                
    };

我没有测试这个,但你明白了。

安德鲁·伯内特·汤普森在这里已经提到了,但他也写道,它对你不起作用。我不明白,也不明白为什么。因此,让我解释一下这个问题:

引入Nagle算法是为了避免许多小数据包必须通过TCP网络发送的情况。任何当前最先进的TCP堆栈都支持Nagle的al