抱歉长度,这是必要的 .
Introduction
我正在使用C#4.0 for Windows Vista / 7开发一个远程桌面软件(只是为了好玩) . 我已经遇到了基本障碍:我有一个强大的UDP消息系统,相对干净的程序设计,我有一个镜像驱动程序(来自DemoForge的免费DFMirage镜像驱动程序)启动并运行,我已经为所有人实现了NAT遍历除对称NAT之外的NAT类型(存在于公司防火墙情况下) .
关于屏幕传输/共享,由于镜像驱动程序,我会自动通知已更改的屏幕区域,我可以简单地将镜像驱动程序不断变化的屏幕位图封送到我自己的位图 . 然后我将屏幕区域压缩为PNG并将其从服务器发送到我的客户端 . 事情看起来很不错,但还不够快 . 它和VNC一样慢(顺便说一下,我不使用VNC协议,只是一个自定义的业余协议) .
从最慢的远程桌面软件到最快的,列表通常从所有类似VNC的实现开始,然后爬到Microsoft Windows远程桌面......然后...... TeamViewer . 对CrossLoop,LogMeIn不太确定 - 我没有使用它们,但TeamViewer非常快 . 它真的很直播 . 我在命令提示符上运行了一个 tree
命令,它以20毫秒的延迟更新 . 我可以浏览网页比我的笔记本电脑慢几毫秒 . 在Visual Studio中垂直滚动代码的延迟时间为50毫秒 . 想想TeamViewer的屏幕传输解决方案必须具备多么强大的功能才能实现这一切 .
VNC使用基于轮询的钩子来检测屏幕变化和暴力屏幕捕获/比较最坏的情况 . 在最好的情况下,他们使用像DFMirage这样的镜像驱动程序 . 我在这个级别 . 他们使用称为RFB协议的东西 .
Microsoft Windows远程桌面显然比VNC高出一步 . 我从StackOverflow的某个地方听说,Windows远程桌面不会发送屏幕位图,而是发送实际的绘图命令 . 这非常棒,因为它可以发送简单的文本(在此坐标处绘制此矩形并使用此渐变对其进行着色)!远程桌面确实非常快 - 而且它是在家工作的标准方式 . 它使用了一种称为RDP协议的东西 .
现在TeamViewer对我来说是一个完全的谜 . 显然,他们发布了第2版的源代码(截至2012年2月,TeamViewer版本为7) . 人们已经阅读过它并说版本2没用 - 它只是对VNC进行自动NAT遍历的一些改进 .
但版本7 ......现在它的速度非常快 . 我的意思是,它实际上比Windows远程桌面更快 . 我用TeamViewer流式传输DirectX 3D游戏(1 fps,但Windows远程桌面甚至不允许DirectX运行) .
顺便说一句,TeamViewer在没有镜像驱动程序的情况下完成所有这些操作有一个选项可以安装一个,它会更快一点 .
The Question
My question is, how is TeamViewer so fast? 一定不可能 . 如果你是非常慷慨的,需要时间来通过TeamViewer 's servers (TeamViewer bypasses corporate Symmetric NATs by simply proxying traffic through their servers). And that libjpeg-turbo compression would take time to compress. High-quality JPG compression takes 175 milliseconds for a full 1920 by 1080 screenshot for me. And that number goes up if the host'计算机运行Atom处理器 . 我只是没有使用过网络监视器,而TeamViewer在500 Kbps和1 Mbps的速度下仍然是无滞后的(VNC软件在该传输速率下滞后几秒钟) . 在我的 tree
命令提示符测试期间,TeamViewer以1 Mbps的速率接收入站数据,仍然运行5-6 fps . VNC和远程桌面不这样做 . 又怎样?
答案有点复杂和错综复杂,所以请只是说它是因为他们使用UDP而不是TCP(你是否认为他们确实使用TCP就像成功一样) .
我希望在StackOverflow上有一个TeamViewer开发人员 .
Potential Answers
一旦人们回复,将更新此内容 .
- 首先,我的想法是TeamViewer具有非常精细的网络控制 . 例如,他们将大数据包拆分到MTU大小之下,从不浪费旅行 . 它们可能具有各种奇特的钩子来检测屏幕变化以及极快的XOR图像比较 .
5 回答
这里最基本的可能是你不想传输静态图像而只是改变图像,这基本上类似于 video stream .
我最好的猜测是一些非常有效(并且经过大量专业化和优化)的运动补偿算法,因为通用桌面使用的大部分实际变化是元素的线性移动(滚动文本,移动窗口等) . 反对元素转换) .
1 FPS的DirectX 3D性能似乎在一定程度上证实了我的猜测 .
您会发现TeamViewer很少需要通过自己的服务器中继流量 . TeamViewer使用NAT遍历渗透NAT和NAT复杂的网络(我认为它是UDP hole-punching,如Google's libjingle) .
他们确实使用自己的服务器给中间人进行握手和连接设置,但大多数时候客户端和服务器之间的关系都是P2P(最好的情况是握手成功时) . 如果NAT遍历失败,那么TeamViewer确实会通过自己的服务器中继流量 .
但是,当客户端支持双NAT时,我才会看到它这样做 .
有点迟到的答案,但我建议你看一下名为ConferenceXP的codeplex上一个不为人知的项目
提供完整的源(它是巨大的!) . 它实现了RTP protocol .
有人建议,这听起来确实比视频流更像图像流 . JPEG / PNG压缩不适用于这些类型的速度,因此请忘记它们 .
想象一下,在您的系统上有一个录制编解码器,可以实时记录传入的视频流(您的屏幕) . 有点像Fraps . 然后想象一下另一侧的视频播放编解码器(远程客户端) . 由于高清录像机可以做到这一点(实时录制,甚至可以从同一个高清播放),最后也应如此 . HD肯定无法比您阅读显示器更快地提供图像,因此这不是瓶颈 . 瓶颈是视频编解码器 . 你会发现编码器比解码器更容易出问题,因为所有的解码器都是免费的 .
我不是说这很简单;我自己使用DirectShow对视频文件进行编码,到目前为止还不是实时的 . 但鉴于正确的编解码器,我确信它可以工作 .
奇怪 . 但根据我的经验,TeamViewer并不比VNC更快/响应更快,只是更容易设置 . 我有一些win-boxen,我通过OpenVPN VNC进入(所以有另一个开销层),这是在便宜的Cable(512 up)上,我发现正确设置TightVNC比TeamViewer对同一盒子更敏感 . RDP(自然地)更是如此,因为大部分它发送GUI绘图命令而不是位图图块 .
这让我们:
为什么不使用VNC?有很多开源解决方案,而Tight现在可能在它的游戏之上 .
高级VNC实现使用有损压缩,这似乎比您选择的PNG获得更好的结果 . 此外,IIRC还使用zlib压缩剩余的有效负载 . Bothj Tight和UltraVNC都有非常优化的算法,特别是对于Windows . 最重要的是Tight是开源的 .
如果win boxen是您的主要目标,RDP可能是更好的选择,并且具有开源实现(rdesktop)
如果* nix boxen是您的主要目标,NX可能是更好的选择并且具有开源实现(FreeNX,尽管不像NoMachine的专有产品那样优化) .
如果压缩JPEG是你的算法的一个性能问题,我很确定图像比较仍然会带走一些性能 . 我敢打赌,他们针对每种特定情况使用最佳情况压缩,即对于大型帧有损,对于较小的帧,有些快速和脏的内部无效,比较图像的比特并且仅发送排序差异和一堆其他优化技巧 .
而且很多这些技巧必须出现在Tight> 2.0中,因为根据我的经验,它击败了TeamViewer性能wyse,YMMV .
另外,对C语言的JIT编译运行时的选择可能会从性能优势中脱颖而出,尤其是在内存受限的机器中(当Windows开始大量使用页面文件时,很多性能调整会进入马桶) . 并且您将需要内存来保留以前的图像状态以进行内部比较DF海市蜃楼给你什么 .