TeamViewer如何实现快速远程控制?

170

很抱歉篇幅有点长,但这是必须的。

介绍

我正在为Windows Vista/7使用C# 4.0开发远程桌面软件(只是出于兴趣)。我已经克服了基本的障碍:我拥有一个强大的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协议的东西。

微软的远程桌面似乎比VNC更进一步。我从StackOverflow上听说,Windows远程桌面不会发送屏幕位图,而是实际的绘图命令。这非常聪明,因为它可以只发送简单的文本(在这个坐标处绘制矩形并用这个渐变色彩填充)!远程桌面真的很快,而且它是在家里工作的标准方式。它使用一种叫做RDP协议的东西。

现在,TeamViewer对我来说完全是个谜。显然,他们发布了第2版的源代码(截至2012年2月,TeamViewer是第7版)。人们已经阅读了它,并说第2版是无用的——它只是在自动NAT穿透方面有了一些改进,超过VNC只有一点点。

但是第7版……现在它速度非常快。我的意思是,它实际上比Windows远程桌面还要快。我用TeamViewer流式传输DirectX 3D游戏(1 fps),但Windows远程桌面甚至不允许DirectX运行。

顺便说一句,TeamViewer所有这些都没有使用镜像驱动程序。有一个选项可以安装一个驱动程序,速度会稍微快一点。

问题

我的问题是,TeamViewer是如何做到如此快速的?这似乎是不可能的。如果您有1920 x 1080分辨率,即使是24位深度(16位深度会明显很丑),仍然需要6,220,800字节的原始数据。即使使用libjpeg-turbo(一种最快的JPG压缩库,由大型企业使用),将其压缩到30KB(非常慷慨),也需要时间通过TeamViewer的服务器进行路由(TeamViewer通过简单地通过其服务器代理流量来绕过公司对称NAT)。而且,libjpeg-turbo压缩需要时间。高质量的JPG压缩对于我来说需要175毫秒才能完成1920 x 1080的全屏截图。如果主机计算机运行Atom处理器,则该数字会增加。我根本不明白TeamViewer如何如此优化其屏幕传输。同样,小尺寸的图像可能会被高度压缩,但至少需要数十毫秒才能压缩。大尺寸的图像不需要时间来压缩,但需要很长时间才能完成。不知何故,TeamViewer完成了整个过程,每秒获得大约20-25帧。我使用了网络监视器,以500 Kbps和1 Mbps的速度使用TeamViewer仍然没有延迟(VNC软件在传输速率为那个时会有几秒钟的延迟)。在我的tree命令提示符测试期间,TeamViewer以1 Mbps的速率接收入站数据,仍以5-6 fps运行。 VNC和远程桌面做不到这一点。所以,怎么做到的?
答案可能会比较复杂和复杂,请不要发表您的2美分,如果您只会说它是因为他们使用UDP而不是TCP的话(您会相信他们实际上也同样成功地使用TCP)。
希望StackOverflow上有TeamViewer的开发人员。
  • 我的想法是,首先,TeamViewer具有非常出色的网络控制。例如,他们将大型数据包分割为刚好低于MTU大小的小块,并且从不浪费行程。他们可能拥有各种花哨的钩子来检测屏幕变化,以及极快的XOR图像比较。

  • 1
    你尝试过反向工程协议吗?(看起来他们在会话设置中使用PKI,所以这可能不容易,如果可行的话) - Kimvais
    6
    对于这个问题的回答取决于公司愿意分享其最重要的商业机密,这是使他们继续经营的关键。如果他们坚定地拒绝分享,那么唯一得到肯定回答的方法就是给他们打电话。我猜你可以询问他们的专利信息。 - Hans Passant
    6
    很奇怪,我并没有发现它比远程桌面快 - 相反,它慢得多!对于我来说,远程桌面要快得多 - 更像是使用本地虚拟机。你是在互联网上进行测试还是在某种本地设置上进行测试?你是否已经打开了防火墙以允许直接的TeamViewer连接? - NickG
    1
    看起来你只在本地网络上进行测试。从我的经验来看,TeamViewer使用有损压缩(在慢速连接下,质量有时真的很差)。VNC是否比TeamViewer使用更多的处理时间和更少的带宽,反之亦然?然后根据您的环境(两台计算机的处理器功率和网络链接质量),有时VNC可能会更快,有时TeamViewer可能会更快。 - Axel
    不,我不仅在本地网络上进行测试。 - Jason
    显示剩余2条评论
    5个回答

    86

    这里最基本的事情可能是,你不想传输静态图像,而只需要传输图像的 变化,这本质上类似于 视频流

    我猜测最好的方法是使用一些非常高效(并且经过专门和优化)的运动补偿算法,因为在通用桌面使用中,大部分实际变化是元素的 线性 移动(滚动文本、移动窗口等,而不是元素的转换)。

    DirectX 3D每秒1帧的性能在某种程度上证实了我的猜测。


    1
    有免费的TechSmith屏幕捕获编解码器。它可以高效地压缩并且不会失真。 - sinni800
    TechSmith网站提供2个解码器免费下载。但是它们单独使用是无用的,因为屏幕录制软件是昂贵的。 - Elmue
    应用程序的旧XP版本在低资源PC上具有非常好的性能。 - user1005462

    30
    你会发现,TeamViewer 很少需要通过自己的服务器中继流量。TeamViewer 使用 NAT 穿透技术(我认为这类似于UDP打洞,就像Google的libjingle)穿透复杂的 NAT 和网络。他们确实使用自己的服务器来充当中间人以进行握手和连接设置,但大多数情况下,客户端和服务器之间的关系将是 P2P(最好的情况是握手成功时)。如果 NAT 穿透失败,则 TeamViewer 将确实通过自己的服务器中继流量。我只在客户端处于双重 NAT 的情况下见过它这样做。

    5
    很少的公司防火墙允许NAT穿透或UPnP,而这正是TeamViewer的主要市场。我怀疑大多数连接在现实生活中都是通过中继实现的... - NickG
    27
    有时候,即使是在企业防火墙或NAT的限制下,你也可以“强行通道”,Skype在这方面做得相当不错。基本上,客户端A发送一个请求,该请求将被NAT/防火墙阻止,并告知外部服务器所使用的端口。然后,客户端B从外部服务器获取端口信息并连接到该端口。A的NAT会认为这是对第一个请求的回复(实际上被B的NAT阻止了),并将其放行。当A在该连接上作出回应时,B的NAT会让它通过,因为连接是由B发起的。=>你们已经建立了连接。 - Axel
    许多公司只有http代理服务器,而没有网络地址转换(NAT)和路由到外部网络。在这种情况下,Teamviewer通过http端口443创建隧道。这是TCP协议,但Teamviewer仍然非常快速。 - sinni800
    @Axel +1 很好的解释和非常迷人的技术。你知道这种挖掘更多信息的方法有没有名称吗?干杯。 - Daniel Liuzzi
    2
    @Daniel:开始阅读维基百科上关于“UDP打洞”和“STUN”的文章。 - Axel
    1
    @DanielLiuzzi Google的开源库libjingle包含一个打洞器:https://developers.google.com/talk/libjingle/developer_guide。他们曾经(可能现在仍在使用,我不确定)用它来进行GChat、Hangouts等通信。 - Jamie Edwards

    8

    正如有人所建议的那样,这听起来更像是视频流而不是图像流。

    JPEG/PNG压缩并不适用于这种速度,所以请忘记它们。

    想象一下,在您的系统上有一个录制编解码器,可以实时记录传入的视频流(您的屏幕),有点像Fraps。然后在另一侧(远程客户端)使用视频播放编解码器。就像高清录像机可以做到(实时录制甚至从同一硬盘实时播放),最终你也应该能做到。高清肯定无法比你阅读显示器更快地提供图像,因此这不是瓶颈。瓶颈是视频编解码器。你会发现编码器比解码器更成问题,因为所有解码器大多都是免费的。

    我不是说这很简单;我自己使用DirectShow编码视频文件,但远非实时。但是,如果使用正确的编解码器,我相信它可以工作。


    “正如有人所建议的那样,这听起来更像是视频流而不是图像流。” 我也相信这个理论。TeamViewer将视频(以及选择时的音频)流记录为一个单一的流并同时发送到客户端。 - FLASHCODER

    4

    我的猜测是:电视使用x264编解码器,该编解码器具有商业许可证(否则TeamViewer将不得不发布其源代码)。在某个时间点(5年前以上),我记得x264的主要开发人员写了一篇关于他为低延迟编码所做的改进的文章(如果您延迟几帧,则编码器可以更好地压缩),此外他还提到了一些其他与TeamViewer类似的用途相关的改进。在那篇文章中,他提到了通过视频流播放quake而没有明显问题。当时我很确定谁是这些改进的赞助商,因为TeamViewer基本上是当时唯一的选择。x264是H264视频编解码器的开源实现,它是非常出色的实现,也是最好的实现之一。同时,它也经过了极好的优化。由于x264的极好实现,您在较低的CPU负载下使用TV可以获得更好的结果。AnyDesk和Chrome Remote Desk使用libvpx,其优化和视频质量都不如x264。

    然而,我认为TeamView无法击败微软的RDP。对我来说,它是最好的,但它只能在Windows PC之间或从Mac到Windows之间运行。TV甚至可以在手机上运行。
    更新:文章是在2010年1月写的,所以那项工作大约是10年前完成的。另外,我犯了一个错误:他玩的是使命召唤,而不是雷神之锤。当你发布你的问题时,如果我猜得对的话,TeamViewer已经使用了那项工作3年了。 从Web Archive阅读该博客文章:x264: the best low-latency video streaming platform in the world。当我在2010年阅读这篇文章时,我确信作者提到的“要求不透露姓名的初创企业”就是TeamViewer。

    1
    你确定AnyDesk使用libvpx吗?他们宣传DeskRT是他们自己专门为桌面环境设计的编解码器。 - tunafish24

    1

    奇怪的是,根据我的经验,TeamViewer并不比VNC更快/响应更快,只是更容易设置。我有几个win-boxen,我通过OpenVPN进行VNC(因此还有另一个开销层),这在廉价的Cable(512 up)上,我发现正确设置的TightVNC比TeamViewer对同一boxen更具响应性。RDP(自然而然)更是如此,因为它主要发送GUI绘图命令而不是位图瓷砖。

    这就带来了:

    1. 为什么不使用VNC?有大量的开源解决方案,而Tight现在可能是最好的。

    2. 高级VNC实现使用有损压缩,似乎比您选择的PNG取得更好的结果。此外,我IRC负载的其余部分也使用zlib压缩。Tight和UltraVNC都具有非常优化的算法,特别是针对Windows。除此之外,Tight是开源的。

    3. 如果Win Boxen是您的主要目标,则RDP可能是更好的选择,并且具有开源实现(rdesktop)

    4. 如果*nix Boxen是您的主要目标,则NX可能是更好的选择,并且具有开源实现(FreeNX,尽管不像NoMachine的专有产品那样优化)。

    如果压缩JPEG对您的算法是一个性能问题,我很确定图像比较仍然会消耗一些性能。我敢打赌他们为每种特定情况使用最佳压缩,即对于大帧使用有损压缩,对于较小的帧使用一些快速而脏的内部无损压缩,比较图像位并仅发送某种差异和一堆其他优化技巧。

    许多这些技巧必须在 Tight > 2.0 中存在,因为根据我的经验,它的性能比 TeamViewer 好得多,当然你的情况可能有所不同。

    此外,选择 JIT 编译的运行时而不是像 C++ 这样的东西可能会削弱您的性能优势,特别是在内存受限的机器上(当 Windows 开始密集使用页面文件时,很多性能调整都将付之东流)。并且您需要内存来保留以前的图像状态,以进行内部比较,除了 DF Mirage 给您的内容。


    9
    当有人将VNC作为TeamViewer的替代方案时,我感到很烦。我想说的是,也许你还没有使用过TeamViewer,不知道它相对于VNC等免费软件的优点?VNC可能适用于访问自己的计算机,但对于屏幕共享和举办会议等任务来说,它根本无法与之相比。据我上次查看,VNC甚至没有任何开放中继服务器,因此在95%的情况下,它都无法正常工作(除非您拥有并运行自己的防火墙或服务器)。 - NickG
    6
    讨论并非关于 VNC 客户端工具与 TeamViewer 的比较(我每天都广泛使用两者,尽管我操作了很多防火墙和服务器,并拥有不少)。讨论的是协议的内部工作及其实现。 - Bojan Markovic
    刚刚在慢速3G网络上尝试了UltraVNC和TeamViewer,性能差异非常大。使用UltraVNC时,在单击远程计算机上的某个内容和看到响应之间经历了1-2秒的延迟。太缓慢了,无法使用。而TeamViewer则快得多(与RDP一样快),足以在同一链接上使用。 - John Reynolds
    我收到的关于这个答案的评论真是荒谬。人们在VNC客户端开发几乎停滞不前的4-5年后才来,而TeamViewer继续投入大量开发资源来优化他们的软件,完全忽略了我的建议的要点,即作为软件开发人员,与其从0行代码开始重新发明轮子,不如从开源VNC实现开始,并从那里开始至少覆盖一些(少量)由TeamViewer等已经覆盖的地面。 - Bojan Markovic
    我现在白天经常遇到严重的网络拥堵问题...而且...远程桌面在低 Mbps 下无法使用..而在 1Mbps 甚至更低的速度下..TeamViewer 对于一个 1600x1200 的 VPS 是可用的!..当然有点卡顿,但你仍然可以使用它...即使是双倍速度的远程桌面也会经常断开连接..或者如果它能工作,那么它会非常卡顿..就像每次点击都要数很多秒。我发誓 TeamViewer 就像魔法一样。我相信 VNC 更像远程桌面而不是 TeamViewer。 - ycomp
    不要关于旧版本的问题,TeamViewer 9-12版本更好还是支持XP的版本。 - user1005462

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接