Извините за длину, это необходимо.
Введение
Я разрабатываю программное обеспечение для удаленного рабочего стола (просто для удовольствия) в С# 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-изображений.