我正在编写一个“远程控制”应用程序,当用户点击应用程序中的按钮时,该应用程序通过Wifi将单个字节传输到我的LAN上的本地服务器.因此,应用程序的感知响应性/及时性对于良好的用户体验非常重要.
通过USB电缆将手机连接到我的电脑并在调试模式下运行应用程序,TCP连接似乎可以在用户点按按钮时快速传输数据包.
当手机与PC断开连接时,用户最多可以点击7个按钮(因此在发送所有7个字节之前,用1个字节的有效载荷进行7个“发送”命令.)如果用户点击按钮并在点击之间稍微等待,似乎有1秒的延迟.
我已经尝试将Socket.NoDelay设置为True和False,它似乎没有任何区别.
为了了解发生了什么,我使用了一个数据包嗅探器来查看流量是什么样的.
>当手机通过USB连接到PC(使用Wifi连接)时,每个字节都在自己的数据包中间隔约200ms.
>当手机在自己的Wifi连接上运行(与USB断开连接)时,字节仍然有自己的数据包,但它们都以4或5个数据包的突发组合在一起,每个组与下一个相距约1000毫秒.
顺便说一句,我的Wifi网络到服务器的Ping时间是从我的笔记本电脑测量的低2ms.
我意识到缓冲“发送”可能会让手机节省能量,但有没有办法禁用这种“延迟”?应用程序的响应能力比节省电力更重要.
首先,应该忽略调试器中的性能测试.原因是无论操作系统/语言/ IDE如何,记录堆栈跟踪的额外开销总是会降低应用程序的速度.应该在发布模式下对应用程序进行性能分析,并与调试器断开连接.在你的情况下它实际上更慢的断开!好吧,让我们尝试优化它.
如果您怀疑数据包正在被缓冲(这是一个合理的假设),您是否尝试过发送更大的数据包?尝试线性增加数据包大小和测量延迟.你可以在设备上的代码中编写一个简单的微型分析器,即:使用DateTime.Now或Stopwatch类来记录延迟与数据包大小.绘制该图可能会让您对您的理论是否正确有一个很好的了解.如果您发现10个字节(甚至100个字节)的数据包立即被发送,那么我建议每次传输只需推送更多数据.这是一个我知道的蹩脚黑客,但如果不是这样的话……
最后你说你正在使用TCP.你能试试UDP吗? TCP不是为实时通信而设计的,而是为准确的通信而设计的.相比之下UDP不是错误检查,你不能保证交付,但你可以期待更快(更轻量级,更低延迟)的性能. Skype和在线游戏等网络建立在UDP而非TCP上.如果您确实需要确认收据,您可以使用自己的Cyclic Redundancy Check进行错误检查和Request/Response (acknowledgement) protocol,通过UDP构建自己的微协议.
这样的协议确实存在,请看Reliable UDP中讨论的Reliable UDP.有一个基于Java的RUDP实现,但我确信某些部分可以移植到C#.当然,第一步是测试UDP是否真的有帮助!
找到上一个讨论该问题的问题.也许是一个Wp7问题?
Poor UDP performance with Windows Phone 7.1 (Mango)
仍然有兴趣看看增加数据包大小或切换到UDP是否有效
好吧所以这两个建议都没有用.我找到了Nagle算法的描述,它按照你的描述对数据包进行分组.设置NoDelay应该有所帮助,但正如你所说,不是.
http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.nodelay.aspx
也.请参阅上一个问题,其中Keepalive和NoDelay设置为开/关以手动刷新队列.他的证据很轶事,值得一试.您可以试一试并编辑您的问题以发布更多最新结果吗?