Perdón por la longitud, es algo necesario.
Introducción
Estoy desarrollando un software de escritorio remoto (solo por diversión) en C # 4.0 para Windows Vista / 7. He superado obstáculos básicos: tengo un sistema de mensajería UDP robusto, un diseño de programa relativamente limpio, tengo un controlador espejo (el controlador espejo DFMirage gratuito de DemoForge) en funcionamiento, y he implementado NAT transversal para todos Tipos de NAT excepto NAT simétricos (presente en situaciones de firewall corporativo).
Con respecto a la transferencia / uso compartido de pantalla, gracias al controlador de espejo, se me notifica automáticamente sobre las regiones de pantalla cambiadas y simplemente puedo ordenar el mapa de bits de la pantalla en constante cambio del controlador de espejo a mi propio mapa de bits. Luego comprimo la región de la pantalla como PNG y la envío desde el servidor a mi cliente. Las cosas se ven bastante bien, pero no es lo suficientemente rápido. Es tan lento como VNC (por cierto, no uso el protocolo VNC, solo un protocolo amateur personalizado).
Desde el software de escritorio remoto más lento hasta el más rápido, la lista generalmente comienza en todas las implementaciones similares a VNC, luego sube a Escritorio remoto de Microsoft Windows ... y luego ... TeamViewer. No estoy muy seguro acerca de CrossLoop, LogMeIn: no los he usado, pero TeamViewer es increíblemente rápido. Es literalmente en vivo. Ejecuté un tree
comando en el símbolo del sistema y se actualizó con 20 ms de retraso. Puedo navegar por la web solo unos milisegundos más lento que en mi computadora portátil. El código de desplazamiento vertical en Visual Studio tiene un retraso de 50 ms. Piense en lo sólida que debe ser la solución de transferencia de pantalla de TeamViewer para lograr todo esto.
Los VNC utilizan ganchos basados en encuestas para detectar el cambio de pantalla y la captura / comparación de pantalla de fuerza bruta en su peor momento. En su mejor momento, utilizan un controlador de espejo como DFMirage. Estoy a este nivel Y usan algo llamado protocolo RFB.
El escritorio remoto de Microsoft Windows aparentemente va un paso más alto que VNC. Escuché, desde algún lugar de StackOverflow, que el Escritorio remoto de Windows no envía mapas de bits de pantalla, sino comandos de dibujo reales. ¡Eso es bastante brillante, porque puede enviar texto simple (dibuja este rectángulo en esta coordenada y coloréalo con este degradado)! Remote Desktop realmente es bastante rápido, y es la forma estándar de trabajar desde casa. Y usa algo llamado protocolo RDP.
Ahora TeamViewer es un completo misterio para mí. Aparentemente, lanzaron su código fuente para la Versión 2 (TeamViewer es la Versión 7 a partir de febrero de 2012). La gente lo ha leído y dice que la Versión 2 es inútil, que solo son algunas mejoras sobre VNC con el recorrido automático NAT.
Pero la Versión 7 ... es ridículamente rápida ahora. Quiero decir, en realidad es más rápido que el Escritorio remoto de Windows. He transmitido juegos DirectX 3D con TeamViewer (a 1 fps, pero Windows Remote Desktop ni siquiera permite que se ejecute DirectX).
Por cierto, TeamViewer hace todo esto sin un controlador espejo. Hay una opción para instalar uno, y se vuelve un poco más rápido.
La pregunta
Mi pregunta es, ¿cómo es TeamViewer tan rápido?No debe ser posible. Si tiene una resolución de 1920 por 1080, incluso a una profundidad de 24 bits (la profundidad de 16 bits sería notablemente fea), todavía son 6.220.800 bytes sin procesar. Incluso usar libjpeg-turbo (una de las bibliotecas de compresión JPG más rápidas utilizadas por las grandes corporaciones), comprimirlo a 30 KB (seamos extremadamente generosos), llevaría tiempo enrutar a través de los servidores de TeamViewer (TeamViewer evita los NAT simétricos corporativos simplemente representando el tráfico a través de sus servidores) Y esa compresión libjpeg-turbo tomaría tiempo para comprimir. La compresión JPG de alta calidad toma 175 milisegundos para una captura de pantalla completa de 1920 por 1080 para mí. Y ese número aumenta si la computadora del host ejecuta un procesador Atom. Simplemente no entiendo cómo TeamViewer ha optimizado tan bien su transferencia de pantalla. Una vez más, las imágenes de pequeño tamaño pueden estar muy comprimidas, pero tome al menos decenas de milisegundos para comprimir. Las imágenes de gran tamaño no tardan en comprimirse, pero tardan mucho en pasar. De alguna manera, TeamViewer completa todo este proceso para obtener aproximadamente 20-25 cuadros por segundo. He usado un monitor de red, y TeamViewer sigue sin retraso a velocidades de 500 Kbps y 1 Mbps (retraso del software VNC durante unos segundos a esa velocidad de transferencia). Durante mitree
Prueba de símbolo del sistema, TeamViewer estaba recibiendo datos entrantes a una velocidad de 1 Mbps y todavía ejecutaba 5-6 fps. VNC y el escritorio remoto no hacen eso. ¿Así que cómo?
Las respuestas serán algo complicadas e intrincadas, así que no publique sus $ 0.02 si solo va a decir que es porque usan UDP en lugar de TCP (aunque, ¿creería que realmente usan TCP con el mismo éxito?)
Espero que haya un desarrollador de TeamViewer en algún lugar aquí en StackOverflow.
Respuestas potenciales
Actualizará esto una vez que la gente responda.
- Mis pensamientos son, en primer lugar, que TeamViewer tiene un control de red muy bueno. Por ejemplo, dividen paquetes grandes por debajo del tamaño de MTU y nunca desperdician un viaje. Probablemente tengan todo tipo de ganchos elegantes para detectar cambios de pantalla junto con comparaciones de imágenes XOR extremadamente rápidas.
Respuestas:
Probablemente, lo más fundamental aquí es que no desea transmitir imágenes estáticas, sino que solo cambia las imágenes, lo que esencialmente es análogo al flujo de video .
Mi mejor conjetura es un algoritmo de compensación de movimiento muy eficiente (y altamente especializado y optimizado), porque la mayor parte del cambio real en el uso genérico del escritorio es el movimiento lineal de elementos (desplazamiento de texto, ventanas móviles, etc. en oposición a la transformación de elementos).
El rendimiento DirectX 3D de 1 FPS parece confirmar mi suposición hasta cierto punto.
fuente
Descubrirá que TeamViewer rara vez necesita retransmitir el tráfico a través de sus propios servidores. TeamViewer penetra en NAT y en las redes complicadas por NAT usando el recorrido NAT (creo que es un agujero UDP , como el libjingle de Google ).
Utilizan sus propios servidores para intermediarios con el fin de hacer la configuración de conexión y conexión, pero la mayoría de las veces la relación entre el cliente y el servidor será P2P (el mejor de los casos, cuando la comunicación es exitosa). Si falla el recorrido NAT, TeamViewer transmitirá el tráfico a través de sus propios servidores.
Sin embargo, solo lo he visto hacer esto cuando un cliente ha estado detrás de doble NAT.
fuente
Respuesta un poco tardía, pero le sugiero que eche un vistazo a un proyecto no conocido en codeplex llamado ConferenceXP
Se proporciona la fuente completa (¡es enorme!). Implementa el protocolo RTP .
fuente
De hecho, parece que la transmisión de video es más que la transmisión de imágenes, como alguien sugirió. La compresión JPEG / PNG no está dirigida a este tipo de velocidades, así que olvídate de ellas.
Imagine tener un códec de grabación en su sistema que pueda grabar en tiempo real una transmisión de video entrante (su pantalla). Un poco como Fraps tal vez. Luego imagine un códec de reproducción de video en el otro lado (el cliente remoto). Como los grabadores HD pueden hacerlo (graba en vivo e incluso reproduce en vivo desde el mismo HD), al final deberías hacerlo tú. La HD seguramente no puede entregar imágenes más rápido de lo que puede leer su pantalla, por lo que ese no es el cuello de botella. El cuello de botella son los códecs de video. Encontrará que el codificador es mucho más problemático que el decodificador, ya que todos los decodificadores son en su mayoría gratuitos.
No digo que sea simple; Yo mismo he usado DirectShow para codificar un archivo de video, y de momento no es en tiempo real. Pero dado el códec correcto, estoy convencido de que puede funcionar.
fuente
Mi suposición aleatoria es: la televisión usa un códec x264 que tiene una licencia comercial (de lo contrario, TeamViewer tendría que liberar su código fuente). En algún momento (hace más de 5 años), recuerdo que el desarrollador principal de x264 escribió un artículo sobre las mejoras que hizo para la codificación de bajo retardo (si se demora unos pocos fotogramas, los codificadores pueden comprimirse mejor), además mencionó algunas otras mejoras que fueron relevante para uso similar a TeamViewer. En esa publicación mencionó jugar terremoto a través de la transmisión de video sin problemas notables. En aquel entonces, estaba bastante seguro de quién era el patrocinador de estas mejoras, ya que TeamViewer era prácticamente la única opción en ese momento. x264 es una implementación de código abierto del códec de video H264, y es una implementación increíblemente buena, es la mejor. Al mismo tiempo, está extremadamente bien optimizado. Lo más probable es que debido a la implementación extremadamente buena de x264, obtenga resultados mucho mejores con TV con una carga de CPU menor. AnyDesk y Chrome Remote Desk usan libvpx, que no es tan bueno como x264 (optimización y calidad de video inteligente).
Sin embargo, no creo que TeamView pueda vencer el RDP de microsoft. Para mí es lo mejor, sin embargo, solo funciona entre PC con Windows o desde Mac a Windows. La televisión funciona incluso desde móviles.
Actualización: el artículo fue escrito en enero de 2010, por lo que el trabajo se realizó hace aproximadamente 10 años. Además, cometí un error: jugó call of duty, no terremoto. Cuando publicó su pregunta, si mi suposición es correcta, TeamViewer había estado usando ese trabajo durante 3 años. Lea la publicación de blog del archivo web: x264: la mejor plataforma de transmisión de video de baja latencia del mundo . Cuando leí el artículo en 2010, estaba seguro de que el "inicio –que ha solicitado no ser nombrado" que el autor menciona era TeamViewer.
fuente
Extrañamente. pero en mi experiencia, TeamViewer no es más rápido / responde mejor que VNC, solo es más fácil de configurar. Tengo un par de win-boxen en los que utilizo VNC sobre OpenVPN (por lo que hay otra capa superior) y eso está en Cable barato (512 en adelante) y creo que la configuración adecuada de TightVNC es mucho más receptiva que TeamViewer al mismo boxen. RDP (naturalmente) aún más, ya que en gran parte envía comandos de dibujo GUI en lugar de mosaicos de mapa de bits.
Lo que nos lleva a:
¿Por qué no estás usando VNC? Hay una gran cantidad de soluciones de código abierto, y Tight probablemente esté en la cima de su juego en este momento.
Las implementaciones avanzadas de VNC utilizan compresión con pérdida y eso parece lograr mejores resultados que su elección de PNG. Además, IIRC el resto de la carga útil también se aplasta usando zlib. Bothj Tight y UltraVNC tienen algos muy optimizados, especialmente para Windows. Además de eso, Tight es de código abierto.
Si win boxen es su objetivo principal, RDP puede ser una mejor opción y tiene una implementación de código abierto (rdesktop)
Si * nix boxen es su objetivo principal, NX puede ser una mejor opción y tiene una implementación de código abierto (FreeNX, aunque no tan optimizado como el producto patentado de NoMachine).
Si comprimir JPEG es un problema de rendimiento para su algoritmo, estoy bastante seguro de que la comparación de imágenes aún le quitaría algo de rendimiento. Apuesto a que usan la mejor compresión de casos para cada situación específica, es decir, con pérdida para cuadros grandes, algunos internos rápidos y sucios sin pérdida para los más pequeños, comparan bits de imágenes y envían solo diferencias de clasificación y un montón de otros trucos de optimización.
Y muchos de esos trucos deben estar presentes en Tight> 2.0 ya que, de nuevo, en mi experiencia, supera enormemente el rendimiento de TeamViewer, YMMV.
Además, la elección de un tiempo de ejecución compilado JIT sobre algo como C ++ podría tomar una porción de su límite de rendimiento, especialmente en máquinas con memoria limitada (una gran cantidad de ajuste de rendimiento va al baño cuando las ventanas comienzan a usar el archivo de paginación intensamente). Y necesitará memoria para mantener los estados de imagen anteriores para una comparación interna además de lo que le proporciona el espejismo DF.
fuente