[解決済み] TeamViewerはどうしてこんなに速いのですか?
質問
長くてすみません、ちょっと必要なんです。
はじめに
私は、Windows Vista/7 用のリモート デスクトップ ソフトウェアを C# 4.0 で開発しています (単なる楽しみとして)。基本的な障害は克服しました。堅牢な UDP メッセージング システム、比較的クリーンなプログラム設計、ミラー ドライバー (DemoForge の無料の DFMirage ミラー ドライバー) のアップおよび実行、および Symmetric 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 よりも 1 ステップ高いようです。StackOverflow のどこかで聞いたのですが、Windows リモート デスクトップは画面のビットマップを送信するのではなく、実際の描画コマンドを送信するのだそうです。単純なテキスト(この座標にこの矩形を描いて、このグラデーションで色をつける)を送ることができるのですから、これは非常に素晴らしいことです。リモートデスクトップは本当に高速で、自宅で仕事をするときの標準的な方法です。そして、RDP プロトコルと呼ばれるものを使用します。
今、TeamViewer は私にとって完全に謎です。どうやら、Version 2 のソース コードを公開したようです (TeamViewer は 2012 年 2 月現在 Version 7 です)。人々はそれを読んで、バージョン 2 は役に立たない、つまり、VNC に自動 NAT トラバーサルをいくつか追加しただけのものだと言いました。
でも、Version 7 は...もうとんでもなく速いんですよ。つまり、Windows リモート デスクトップよりも実際に速いのです。私は TeamViewer で DirectX 3D ゲームをストリーミングしました (1 fps ですが、Windows リモート デスクトップでは DirectX を実行することさえできません)。
ちなみに、TeamViewer はこのようなことをすべて行います。 なしで ミラードライバを使用しません。1 つインストールするオプションがあり、ほんの少し速くなります。
質問
私の質問は、TeamViewerはどうしてそんなに速いのですか?
それは不可能に違いありません。1920 x 1080 の解像度で 24 ビット深度 (16 ビット深度では著しく醜い) であっても、生で 6,220,800 バイトになります。libjpeg-turbo(大企業で使用されている最速のJPG圧縮ライブラリの1つ)を使用して、30KB(非常に寛大であるとしましょう)に圧縮しても、TeamViewerのサーバーを通過するために時間がかかります(TeamViewerは、単にそのサーバーを介してプロキシトラフィックによって企業のシンメトリックNATをバイパスします)。そして、libjpeg-turbo圧縮は圧縮に時間がかかる。高品質なJPG圧縮は、私の場合、1920×1080のスクリーンショットに175ミリ秒かかります。ホストのコンピュータがAtomプロセッサを搭載している場合、この数字はさらに上がります。TeamViewerがどのように画面転送を最適化しているのか、私には理解できません。繰り返しになりますが、小さいサイズの画像は圧縮率が高いかもしれませんが、圧縮するのに少なくとも数十ミリ秒かかります。大きなサイズの画像は、圧縮に時間はかからないが、転送に時間がかかる。TeamViewerは、なぜかこの一連の処理を完了させ、おおよそ1秒間に20~25フレームを実現しています。ネットワークモニターを使用したところ、TeamViewerは500Kbpsと1Mbpsの速度でもラグがありません(VNCソフトウェアはこの転送速度で数秒のラグが発生します)。私の
tree
コマンドプロンプトのテストでは、TeamViewerは1Mbpsのレートでインバウンドデータを受信し、それでも5-6fpsで動作していました。VNCやリモートデスクトップではこうはいきません。では、どのようにして?
答えはやや複雑で入り組んだものになりますので TCP の代わりに UDP を使用しているからだと言うだけなら、あなたの $0.02 を投稿しないでください。 (実際には TCP をうまく使っているのですが、信じられますか?) 。
この StackOverflow のどこかに TeamViewer の開発者がいることを期待しています。
想定される回答
回答があり次第、更新します。
- 私の考えは、まず第一に、TeamViewer は非常に細かいネットワーク制御を行っているということです。たとえば、大きなパケットを MTU サイズのすぐ下に分割し、決してトリップを無駄にしません。おそらく、非常に高速な XOR イメージ比較とともに、画面の変更を検出するためのあらゆる種類の凝ったフックを備えているのでしょう。
どのように解決するのですか?
ここで最も基本的なことは、おそらく、静止画像を送信するのではなくて、あくまでも 変更 に類似していることです。 ビデオストリーム .
私の推測では、非常に効率的な (そしてかなり特化して最適化された) モーション補正アルゴリズムがあると思われます。 線形
要素の移動 (テキストのスクロール、ウィンドウの移動など。要素の変換とは対照的) です。1 FPS という DirectX 3D パフォーマンスは、私の推測をある程度裏付けているようです。
関連
-
[解決済み] HadoopのMapreduceジョブでJVMを再利用する。
-
[解決済み] spark.sql.shuffle.partitionsとspark.default.parallelismの違いは何ですか?
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] Python 3で「1000000000000000 in range(1000000000000001)」はなぜ速いのですか?
-
[解決済み] JavaScriptでオブジェクトのキー/プロパティの数を効率的にカウントする方法
-
[解決済み] Eclipseを高速化する方法とは?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】インターネット接続が遅い場合のシミュレーション【終了しました
-
[解決済み】なぜMATLABは行列の乗算が速いのか?
-
[解決済み] あなたが見た中で最も馬鹿げたペシミゼーションは何ですか?[閉店]
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 実行時間(高速化)の計算方法
-
[解決済み] spark.sql.shuffle.partitionsとspark.default.parallelismの違いは何ですか?
-
[解決済み] πの値を最も早く求める方法は何ですか?
-
[解決済み】HTTPとHTTPSのパフォーマンス比較
-
[解決済み】2つの範囲が重なっているかどうかをテストする最も効率的な方法は何ですか?
-
[解決済み】JSFがゲッターを複数回呼び出す理由
-
[解決済み】再帰と反復のどちらを選ぶ?
-
[解決済み】インターネット接続が遅い場合のシミュレーション【終了しました
-
[解決済み] SSLはどれくらいのオーバーヘッドを発生させるのですか?
-
[解決済み] Apache Spark: map vs mapPartitions?