Как TeamViewer так быстро?

Извините за длину, это необходимо.

Введение

Я разрабатываю программное обеспечение для удаленного рабочего стола (просто для удовольствия) в С# 4.0 для Windows Vista/7. Я преодолел основные препятствия: у меня есть надежная система обмена сообщениями UDP, относительно чистый дизайн программы, у меня есть зеркальный драйвер (бесплатный зеркальный драйвер DFMirage от DemoForge), и я реализовал обход NAT для всех Типы NAT, за исключением симметричных NAT (присутствуют в корпоративных ситуациях брандмауэра).

Что касается передачи/совместного использования экрана, благодаря зеркальному драйверу, я автоматически уведомляюсь об измененных областях экрана, и я могу просто маршалировать зеркальный драйвер, когда-либо изменяющий растровое изображение экрана, на мое собственное растровое изображение. Затем я сжимаю область экрана как PNG и отправляю ее с сервера на мой клиент. Все выглядит довольно хорошо, но это не достаточно быстро. Он так же медленный, как VNC (кстати, я не использую протокол VNC, просто пользовательский любительский протокол).

От самого медленного программного обеспечения для удаленного рабочего стола до самого быстрого, список обычно начинается на всех реализациях, подобных VNC, а затем поднимается на Microsoft Windows Remote Desktop... и затем... TeamViewer. Не совсем уверен в CrossLoop, LogMeIn - я их не использовал, но TeamViewer безумно быстро. Это довольно буквально живет. Я выполнил команду tree в командной строке, и она обновилась с задержкой 20 мс. Я могу просматривать веб-страницы всего несколько миллисекунд медленнее, чем на моем ноутбуке. Прокрутка кода по вертикали в Visual Studio составляет 50 мс. Подумайте о том, насколько надежным решением для трансляции экрана TeamViewer должно быть все это.

VNC используют опросники, основанные на опросе, для обнаружения смены экрана и захвата экрана с использованием переборки/сравнения в худшем случае. В лучшем случае они используют зеркальный драйвер, такой как DFMirage. Я на этом уровне. И они используют что-то, называемое RFB-протоколом.

Microsoft Windows Remote Desktop, по-видимому, на один шаг выше VNC. Я слышал, откуда-то из StackOverflow, что Windows Remote Desktop не отправляет растровые изображения экрана, а фактические команды рисования. Это довольно блестяще, потому что он может просто отправить простой текст (нарисуйте этот прямоугольник с этой координатой и покрасьте его с помощью этого градиента)! Удаленный рабочий стол действительно довольно быстрый - и это стандартный способ работы из дома. И он использует что-то, называемое протоколом RDP.

Теперь TeamViewer - полная тайна для меня. По-видимому, они выпустили свой исходный код для версии 2 (TeamViewer - версия 7 от февраля 2012 года). Люди прочитали его и сказали, что версия 2 бесполезна - это всего лишь несколько улучшений по сравнению с VNC с автоматическим обходом NAT.

Но версия 7... это смешно быстро. Я имею в виду, что он работает быстрее, чем Windows Remote Desktop. Я транслировал игры DirectX 3D с TeamViewer (с частотой 1 к/с, но Windows Remote Desktop даже не разрешает запуск DirectX).

Кстати, TeamViewer делает все это без зеркального драйвера. Есть возможность установить один, и он становится немного быстрее.

Вопрос

Мой вопрос: насколько TeamViewer так быстро? Это не должно быть возможным. Если у вас есть разрешение 1920 на 1080 даже при 24-битной глубине (глубина 16 бит будет заметно уродливой), это еще 6 220 800 байт. Даже используя libjpeg-turbo (одну из самых быстрых библиотек сжатия JPG, используемую крупными корпорациями), сжатие до 30 КБ (пусть будет очень велико), потребуется время для маршрутизации через серверы TeamViewer (TeamViewer обходит корпоративные Symmetric NAT, просто проксируя трафик через их серверы). И для сжатия libjpeg-turbo потребуется время для сжатия. Высококачественное сжатие JPG занимает 175 миллисекунд для полного снимка 1920 на 1080 для меня. И это число увеличивается, если главный компьютер запускает процессор Atom. Я просто не понимаю, как TeamViewer так хорошо оптимизировал свою передачу экрана. Опять же, мелкие изображения могут быть сильно сжаты, но для сжатия требуется не менее десятков миллисекунд. Большие изображения не требуют времени, чтобы сжимать, но пройти долгое время. Как-то TeamViewer завершает весь этот процесс, чтобы получить примерно 20-25 кадров в секунду. Я использовал сетевой монитор, и TeamViewer по-прежнему безразличен со скоростью 500 Кбит/с и 1 Мбит/с (отставание программного обеспечения VNC в течение нескольких секунд при такой скорости передачи). Во время теста tree Command Prompt TeamViewer получал входящие данные со скоростью 1 Мбит/с и все еще выполнял 5-6 кадров в секунду. VNC и удаленный рабочий стол этого не делают. Итак, как?

Ответы будут несколько сложными и сложными, поэтому, пожалуйста, не публикуйте свои $0.02, если вы только скажете это, потому что они используют UDP вместо TCP (вы считаете, что на самом деле они действительно используют TCP так же успешно).

Я надеюсь, что здесь есть разработчик TeamViewer на StackOverflow.

Потенциальные ответы

Будет обновляться после ответа людей.

  • Мои мысли в первую очередь о том, что TeamViewer имеет очень тонкое сетевое управление. Например, они разбивают большие пакеты только под размер MTU и никогда не тратят время на поездку. У них, вероятно, есть всевозможные причудливые крючки для обнаружения изменений экрана вместе с чрезвычайно быстрыми сравнениями XOR-изображений.

Ответ 1

Самое главное здесь, вероятно, в том, что вы не хотите передавать статические изображения, а только изменения в изображениях, которые по существу аналогичны видеопотоку.

Мое лучшее предположение - это очень эффективный (и сильно специализированный и оптимизированный) алгоритм компенсации движения, поскольку большая часть фактического изменения общего использования рабочего стола - это линейное перемещение элементов (прокрутка текста, перемещение окон и т.д., противоположная преобразованию элементов).

Производительность DirectX 3D в 1 FPS, похоже, в некоторой степени подтверждает мои предположения.

Ответ 2

потребуется время для маршрутизации через сервер TeamViewer (TeamViewer обходит корпоративные Symmetric NAT, просто проксируя трафик через свои серверы)

Вы обнаружите, что TeamViewer редко нуждается в ретрансляции трафика через свои собственные серверы. TeamViewer проникает в NAT и сети, сложные NAT с использованием NAT traversal (я думаю, что это UDP отверстие-перфорация, например Google libjingle).

Они используют свои собственные серверы для среднего человека, чтобы выполнить рукопожатие и настройку соединения, но большую часть времени отношения между клиентом и сервером будут P2P (лучший случай, когда успешное дрожание рук). Если обход NAT не удался, TeamViewer действительно будет передавать трафик через свои собственные серверы.

Я только когда-либо видел это, когда клиент был за двойным NAT.

Ответ 3

Немного поздний ответ, но я предлагаю вам взглянуть на малоизвестный проект на codeplex под названием ConferenceXP

ConferenceXP - это исследовательская платформа с открытым исходным кодом, которая обеспечивает простые, гибкой и расширяемой конференц-связи и совместной работы с использованием сети с высокой пропускной способностью и расширенные мультимедийные возможности Майкрософт Виндоус. ConferenceXP помогает исследователям и преподавателям разрабатывать инновационные приложения и решения, которые широковещательное качество звука и видео в поддержку распределенных в реальном времени сотрудничества и дистанционного обучения.

Предоставляется полный источник (он огромный!). Он реализует протокол RTP.

Ответ 4

Звучит действительно как потоковая передача видео больше, чем потоковое изображение, как кто-то предложил. Сжатие JPEG/PNG не предназначено для этих типов скоростей, поэтому забудьте их.

Представьте, что в вашей системе есть записывающий кодек, который в реальном времени может записывать входящий видеопоток (ваш экран). Возможно, немного похоже на Фрэпса. Затем представьте себе кодек воспроизведения видео с другой стороны (удаленный клиент). Поскольку HD-рекордеры могут это сделать (запись в прямом эфире и даже воспроизведение в реальном времени с одного и того же HD), так и вы, в конце концов. HD, безусловно, не может доставлять изображения быстрее, чем вы можете читать свой дисплей, так что это не узкое место. Узким местом являются видеокодеки. Вы обнаружите, что кодер гораздо больше проблем, чем декодер, поскольку все декодеры в основном свободны.

Я не говорю это просто; Я сам использовал DirectShow для кодирования видеофайла, и это не в реальном времени. Но, учитывая правильный кодек, я убежден, что он может работать.

Ответ 5

Как ни странно. но по моему опыту TeamViewer работает не быстрее/быстрее, чем VNC, его проще настроить. У меня есть пара win-boxen, в которой я VNC над OpenVPN (так что есть еще один верхний слой), и что на дешевом Cable (512 up), и я считаю, что правильно настроить TightVNC гораздо лучше, чем TeamViewer, на тот же самый boxen. RDP (естественно), тем более, что в значительной степени он отправляет команды рисования GUI вместо растровых фрагментов.

Что приводит нас к:

  • Почему вы не используете VNC? Существует множество открытых источников решения и Tight, вероятно, на вершине этой игры прямо сейчас.

  • Усовершенствованные реализации VNC используют сжатие с потерями и, как представляется, лучшие результаты, чем ваш выбор PNG. Кроме того, IIRC остальная часть полезной нагрузки также раздавлен с использованием zlib. Bothj Tight и UltraVNC имеют очень оптимизированные альго, особенно для окон. В дополнение к этому Tight является открытым исходным кодом.

  • Если win boxen является вашей основной целью, RDP может быть лучшим вариантом и имеет реализацию с открытым исходным кодом (rdesktop)

  • Если * nix boxen является вашей основной целью, NX может быть лучшим вариантом и имеет реализацию с открытым исходным кодом (FreeNX, хотя и не так оптимизирован как собственный продукт NoMachine).

Если сжатие JPEG является проблемой производительности для вашего алгоритма, я уверен, что сравнение изображений по-прежнему приведет к снижению производительности. Бьюсь об заклад, они используют сжатие наилучшего случая для каждой конкретной ситуации, т.е. С потерями для больших кадров, некоторые быстрые и грязные внутренние без потерь для меньших, сравнивают бит изображений и отправляют только разницы в сортировке и связке других трюков оптимизации.

И многие из этих трюков должны присутствовать в Tight > 2.0, так как снова, по моему опыту, он превосходит по производительности TeamViewer wyse, YMMV.

Кроме того, выбор скомпилированной среды выполнения JIT над чем-то вроде С++ может занять кусочек от вашего предела производительности, особенно в машинах с ограниченными физическими возможностями (при настройке в окнах интенсивно запускается настройка производительности в туалете). И вам понадобится память, чтобы сохранить предыдущие состояния изображения для внутреннего сравнения поверх того, что дает вам DF мираж.