view paper/main.tex @ 29:81e6e6f33521

Update
author Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
date Wed, 17 Feb 2016 22:06:25 +0900
parents 1e36dc43391b
children d8660bf1da6f
line wrap: on
line source

\documentclass[a4j,12pt]{jreport}
\usepackage[dvipdfmx]{graphicx}
\usepackage{mythesis}
\usepackage{multirow}
\usepackage{here}
\usepackage{url}
\usepackage{listings, jlisting}

\input{dummy} %% font

\lstset{
    language=java, 
    tabsize=2, 
    frame=single, 
    basicstyle={\ttfamily\footnotesize},% 
    identifierstyle={\footnotesize},% 
    commentstyle={\footnotesize\itshape},% 
    keywordstyle={\footnotesize\bfseries},% 
    ndkeywordstyle={\footnotesize},% 
    stringstyle={\footnotesize\ttfamily}, 
    breaklines=true, 
    captionpos=b, 
    columns=[l]{fullflexible},% 
    xrightmargin=0zw,% 
    xleftmargin=1zw,% 
    aboveskip=1zw, 
    numberstyle={\scriptsize},% 
    stepnumber=1, 
    numbersep=0.5zw,% 
    lineskip=-0.5ex, 
    numbers=left 
}
\renewcommand{\lstlistingname}{Code}

\setlength{\itemsep}{-1zh}

\title{PC画面配信システムTreeVNCの NAT への対応}
%\title{Supporting NAT in Screen Sharing System TreeVNC}
\icon{
    \includegraphics[width=80mm,bb=0 0 595 642]{fig/ryukyu.pdf} %%元は 642じゃなくて842
}
\year{平成27年度 卒業論文}
\belongto{琉球大学工学部情報工学科}
\author{125716B 伊波 立樹 \\ 指導教員 {河野 真治} }

%% TreeVNC のNATへの対応
%% マルチスクリーン TreeVNC
%% プリアンブルに記述
%% Figure 環境中で Table 環境の見出しを表示・カウンタの操作に必要
%%
\makeatletter
\newcommand{\figcaption}[1]{\def\@captype{figure}\caption{#1}}
\newcommand{\tblcaption}[1]{\def\@captype{table}\caption{#1}}
\makeatother
\setlength\abovecaptionskip{0pt}

\begin{document}

% タイトル
\maketitle
\baselineskip 17pt plus 1pt minus 1pt

\pagenumbering{roman}
\setcounter{page}{0}

\tableofcontents	% 目次
\listoffigures		% 図目次
\listoftables		% 表目次

%以下のように、章ごとに個別の tex ファイルを作成して、
% main.tex をコンパイルして確認する。
%章分けは個人で違うので下のフォーマットを参考にして下さい。

% はじめに

\chapter{画面共有を利用したコミュニケーション}
授業やゼミ等で、それぞれが PC 端末を持っている場合では、
PC の機能を活かしたコミュニケーションが可能である。

通常の授業では先生の用意した資料、 PC 画面を見ながら授業が進むことが多い。 
ゼミでは発表者を切り替えながら発表を行う。

通常これらの画面を表示するためにプロジェクタが使用されている。
しかし、プロジェクタでは通常の授業の際、参加者はプロジェクタに集中するため、手元の PC をほぼ使用することができない。
更に手元の PC を使う際はプロジェクタと PC を行き来するため、目に負担がかかってしまう。
またゼミの際には発表者を切り替えるたびにプロジェクタにケーブルを差し替える必要がある。
ケーブルの差し替えの際に発表者の PC によってアダプターの種類や解像度の設定によって正常に PC 画面を表示できない場合もある。

画面配信システム TreeVNC\cite{taninari:2011a}は発表者の画面を参加者の PC に表示する。
そのため、参加者は不自由なく手元の PC を使用しながら授業を受ける事が可能になる。
更に発表者の切り替えの際もケーブルの差し替えずに共有する画面の切替を可能としている。

Tree VNC は VNC\cite{vnc} を使用した画面配信を行っている。
しかし通常の VNC では配信側に全ての参加者が接続するため、多人数の際の処理性能が落ちてしまう。
Tree VNC では有線でネットワークに接続した参加者をバイナリツリー状に接続し、 配信コストをクライアントに分散させる仕組みになっている。
そのため、授業で先生の画面を表示する際、多人数の生徒が参加しても処理性能が下がらない。
また、ツリーのルートが参照している VNC サーバーを変更することで、共有する画面の切替が可能となる。

しかし TreeVNC を授業やゼミで使用している中、 様々な問題が発生した。
NATを越えたネットワーク接続に対応しておらず、遠隔地などで授業やゼミに参加することが出来ない。
また、ゼミの際に、マルチディスプレイを使用して画面配信を行う際、すべての画面が配信され、不必要な画面まで表示されてしまう。


そこで、本研究では上記の問題点を解決し、TreeVNCの有用性を評価することで授業やゼミを円滑に行えることを目標とする。

\label{chap:introduction}
\pagenumbering{arabic}

%序論の目安としては1枚半ぐらい.
%英語発表者は,最終予稿の「はじめに」の英訳などを載せてもいいかも.


\chapter{TreeVNC の概念}
\label{chap:concept}

\section{VNC}
VNC(Virtual Network Computing) は、 RFBプロトコルを用いて遠隔操作を行うリモートデスクトップソフトウェアである。
VNC はサーバー側とクライアント(ビューア)側に分かれている。 サーバを起動し、クライアントがサーバに接続を行い遠隔操作を可能とする。

\section{RFB プロトコル}
RFB(remote frame buffer)プロトコル\cite{rfbProtocol}とは、自身の画面を送信し、ネットワーク越しに他者の画面に表示するプロトコルである。
ユーザが居る側をRFBクライアント側と呼び、Framebufferへの更新が行われる側はRFBサーバと呼ぶ。
Framebufferとは、メモリ上に置かれた画像データのことである。
RFBプロトコルでは、最初にプロトコルバージョンの確認や認証が行われる。
その後、クライアントに向けてFramebufferの大きさやデスクトップに付けられた名前などが含まれている初期メッセージが送信される。
RFBサーバ側はFramebufferの更新が行われるたびに、RFBクライアントに対してFramebufferの変更部分だけを送信する。
更にRFBクライアントのFramebufferUpdateRequestが来るとそれに答え返信する。
RFBプロトコルは、描画データに使われるエンコードが多数用意されており、また独自のエンコードを実装することもできるプロトコルである。

\section{多人数で VNC を使用する際の問題}
VNCを使用すればクライアント側にサーバー側の画面を表示することが可能である。 
しかし、図\ref{fig:vnc}のように多人数のクライアントが1つのサーバーに接続してしまうと処理性能が落ちてしまうという問題点がある。

また、 ゼミ等の発表で画面配信者が頻繁に切り替わる場合、配信者が替わる度にアプリケーションを終了し、接続をし直さないといけないという問題がある。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.8]{./images/vnc.pdf}
    \end{center}
    \caption{VNCの構造}
    \label{fig:vnc}
\end{figure}

\section{TreeVNC の構造}
TreeVNC は Java を用いて作成された TightVNC(Tight Virtual Network Computing)\cite{tightvnc} を元に作成されている。

TreeVNC は クライアント同士を接続させ、画面描画のデータを受け取ったクライアントが次のクライアントにデータを流す方式を取っている。
また、サーバへ接続しに来たクライアントをバイナリツリー状に接続する(図\ref{fig:tree})。
バイナリツリー状に接続することで、$N$ 台のクライアントが接続しに来た場合、画面配信の画像データをコピーする回数は従来の VNC ではサーバ側で$N$ 回する必要があるが、TreeVNCでは各ノードが2回ずつコピーするだけで済む。 

TreeVNCで通信される画像のデータ量は大きいため、大きなネットワークスループットが必要である。
そのため、有線接続が必須である。

バイナリツリーのルートのノードを Root Node と呼び、 Root Node に接続されるノードを Node と呼ぶ
Root Node は子 Nodeにデータを流す機能に加え、各 Node の管理、 VNC サーバーから流れてきた画像データの管理を行う。 
Node は 親 Node から送られたデータを 自分の子 Node に流す機能、 逆に子 Node から送られてきたデータを 親 Node に流す機能がある。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.8]{./images/treeVnc.pdf}
    \end{center}
    \caption{構成される木構造}
    \label{fig:tree}
\end{figure}

\newpage

\section{TreeVNC の原理}
従来の VNC と TreeVNC の構造を比較を図\ref{fig:treeVncTheory}に示す。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/treeVncTheory}
    \end{center}
    \caption{ポート一本にかかる負荷}
    \label{fig:treeVncTheory}
\end{figure}

表\ref{tb:treeVncTheory}はポート一本あたりの通信量である。
通常の VNC の場合、クライアント数に比例してポート一本あたりの負荷が増えている。
TreeVNC の場合は1つの Node に対して2台の Node が接続するため、最大でも親から送信されるデータと2つの子に送信するデータ分の負荷になる。

送信するデータ量も通常の VNC の場合 Node 数に比例した量のデータを送信する必要があり、 CPU に負荷がかかってしまう。
それに対して TreeVNC はクライアントが増えても送信するデータはクライアント毎に分散されているため、1台の CPU に掛かる負荷は一定となる。
そのため、性能が低下せずに画面配信を行うことが出来る。

\begin{table}[htbp]
    \begin{center}
        \caption{ポート一本あたりの通信量(N はノード数, d はデータ量)}
        \begin{tabular}{|l|l|l|} \hline
            & 通常の VNC   & TreeVNC \\ \hline
            通信量 & N * d & (2 + 1) * d \\ \hline
        \end{tabular}
        \label{tb:treeVncTheory}
    \end{center}
\end{table}

\newpage

\section{圧縮形式}
TreeVNC は ZRLEE\cite{taninari:2012a} というエンコードでデータのやり取りを行う。
ZRLEE はRFB プロトコルで使えるエンコーディングタイプの ZRLE を元に生成される。

ZRLE は Zlib\cite{zlib} で圧縮されたデータとそのデータのバイト数がヘッダーとして付けて送られてくる。
Zlib は java.util.zip.deflater と java.util.zip.inflater で圧縮と解凍が行える。

しかし、 java.util.zip.deflater は解凍に必要な辞書を書き出す(flush)ことが出来ない。
そのため図\ref{fig:zrleFail} のように、 Zlib圧縮されたデータを途中から受け取ってもデータを正しく解凍することが出来ない。

そこで ZRLEE は 一度 Root Node で受け取った ZRLE のデータを unzip し、 データをupdate rectangle という画面毎のデータに辞書を付けて zip し直すことで初めからデータを呼んでいなくても解凍を行えるようにした(図\ref{fig:zrlee})。
% ZRLEE はupdate rectangle 毎にzip, unzip する
% 一本は上からくる奴の説明が欲しい 図 はUpdate rectangle 
一度 ZRLEE に変換してしまえば子 Node はそのデータをそのまま流すだけで良い。
ただし、deflater と inflater では前回までの通信で得た辞書をクリアしないといけないため、 Root Node と Node 側では毎回新しく作る必要がある。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/zrleFail.pdf}
    \end{center}
    \caption{ZRLEでの問題点}
    \label{fig:zrleFail}
\end{figure}

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/zrlee.pdf}
    \end{center}
    \caption{ZRLEE}
    \label{fig:zrlee}
\end{figure}

\newpage

\section{通信経路}
TreeVNC の通信経路として以下が挙げられる
\begin{itemize}
    \item ある Node から Root Node に直接通信を行う send direct message (Node to Root)
    \item Root Node からある Node に直接通信を行う send direct message (Root to Node)
    \item Root Node から木の末端の Node までのすべての Nodeに通信を行う messeage down tree (Root to Node)
    \item ある Node から木構造を上に辿って Root Nodeまで通信を行う message up tree (Node to Root)
    \item Root Node から配信者の VNC サーバーへの通信を行う send message (Root to VNCServer)
    \item VNC サーバーから Root Node への通信を行う send message (VNCServer to Root)
\end{itemize}

\section{ノード間で行われるメッセージ通信}
RFBプロトコルで提供されているメッセージに加え、 TreeVNC 独自のメッセージを使用している。
TreeVNC で使用されるメッセージの一覧を表\ref{tb:message}に示す。

\begin{table}[htbp]
    \caption{通信経路とメッセージ一覧}
    \scriptsize
    \begin{tabular}{|l|l|l|} \hline
        通信経路            & message                    & 説明 \\ \hline \hline
                                & FIND\_ROOT                 & TreeVNC接続時にRoot Nodeを探す。 \\ \cline{2-3}
        send direct message & WHERE\_TO\_CONNECT         & 接続先をRoot Nodeに聞く。 \\ \cline{2-3}
        (Node to Root)      & LOST\_CHILD                & 子Nodeの切断をRoot Nodeに知らせる。 \\ \hline \hline

                            & FIND\_ROOT\_REPLY          & FIND\_ROOTへの返信。 \\ \cline{2-3}
        send direct message & CONNECT\_TO\_AS\_LEADER    & 左子Nodeとして接続する。接続先のNodeが含まれている。 \\ \cline{2-3}
        (Root to Node)      & CONNECT\_TO                & 右子Nodeとして接続する。接続先のNodeが含まれている。 \\ \hline \hline

        message down tree   & FRAMEBUFFER\_UPDATE        & 画像データ。EncodingTypeを持っている。\\ \cline{2-3}
        (Root to Node)      & CHECK\_DELAY               & 通信の遅延を測定する。 \\ \hline \hline

        message up tree     & CHECK\_DELAY\_REPLY        & CHECK\_DELAYへの返信。 \\ \cline{2-3}
        (Node to Root)      & SERVER\_CHANGE\_REQUEST    & 画面切り替え要求。 \\ \hline \hline

                            & FRAMEBUFFER\_UPDATE\_REPLY & 画像データの要求。 \\ \cline{2-3}
        send message        & SET\_PIXEL\_FORMAT         & pixel値の設定。 \\ \cline{2-3}
        (Root to VNCServer) & SET\_ENCODINGS             & pixelデータのencodeTypeの設定。 \\ \cline{2-3}
                            & KEY\_EVENT                 & キーボードからのイベント。 \\ \cline{2-3}
                            & POINTER\_EVENT             & ポインタからのイベント。 \\ \cline{2-3}
                            & CLIENT\_CUT\_TEXT          & テキストのカットバッファを持った際のmessage。 \\ \hline \hline

                            & FRAMEBUFFER\_UPDATE        & 画像データ。EncodingTypeを持っている。 \\ \cline{2-3}
        send message        & SET\_COLOR\_MAP\_ENTRIES   & 指定されているpixel値にマップするRGB値。 \\ \cline{2-3}
        (VNCServer to Root) & BELL                       & ビープ音を鳴らす。 \\ \cline{2-3}
                            & SERVER\_CUT\_TEXT          & サーバがテキストのカットバッファを持った際のmessage。 \\ \hline
    \end{tabular}
    \label{tb:message}
\end{table}

図\ref{fig:message}は TreeVNC で 新しいNode が Root Node と通信し、木構造を形成するためのメッセージ通信の流れである。
図\ref{fig:message}の手順として

\begin{itemize}
    \item 接続を行う Node は Multicast 通信で Root Node に対してFIND\_ROOTを送信する。
    \item Root NodeがFIND\_ROOTを受信し、FIND\_ROOT\_REPLYを送信する。
    \item Node 側で、どのRoot Nodeに接続するかを選択するパネルが表示される。
    \item Node はパネルで接続するRoot Nodeを選択し、Rootに対して接続先を要求するWHERE\_TO\_CONNECTを送信する。
    \item 受信した Root Node は Node の接続先をCONNECT\_TOで送信する。 Node 3 が接続する場合、Root Node には既に2台の Node が接続している為、 CONNET\_TO で指定する接続先は Node 1となる。
    \item Node は Root の指定した接続先に接続しに行く。
\end{itemize}

を行い、木構造を形成する。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/message.pdf}
    \end{center}
    \caption{node 間で行われるメッセージ通信}
    \label{fig:message}
\end{figure}

\section{MulticastQueue}
配信側の画面が更新されると、 VNCServer から画像データがFRAME\_BUFFER\_UPDATE メッセージとして送られる。
その際、 画像データの更新を複数の Node に同時に伝えるため MulticastQueue というキューに画像データを格納する。

MulticastQueue は java.util.concurrent.CountDownLatch を用いて実装されている。
CountDownLatch は java の並列用のAPIで他のスレッドで実行中の操作が完了するまで、複数のスレッドを待機させることが出来るクラスである。 
CountDownLatch を初期化する際にカウントを設定することができる。 
このカウントはスレッドを開放する際に使用し、 await メソッドでカウントが0になるまでメソッドをブロックする事ができる。

MulticastQueue は put メソッドを使用して データを queue に追加する。 
put の際に CountDownLatch をカウントダウンする。
poll メソッドを使用することで Queue のデータを取得することが出来る。
poll メソッドの実行の際に await メソッドが使われているため、 次の put でデータが来るまでスレッドをブロックする。
スレッドをブロックされた場合 新しいデータが put されると CountDownLatch がカウントダウンされるため、 データの読み込みが再開される。

\newpage

\section{木の再構成}
TreeVNC はバイナリツリーでの接続という特性上 Node が切断されたことを検知できずにいると、Node 同士で構成された木構造が崩れてしまい、新しい Node が接続に来た場合に適切な場所に Node を接続することができなくなってしまう。
木構造を崩さないよう、Node 同士の接続を再構成を行う必要がある。

TreeVNC の木構造のネットワークトポロジーは Root Node が持っている nodeList というリストで管理している。
つまり、Node の接続が切れた場合、木の再構成を行うため Root Node に知らせなければならない。

TreeVNC は LOST\_CHILD というメッセージ通信で Node の切断を検知・木の再構成を行っている。

TreeVNC は VNC サーバーから送られる画像データ(FRAME\_BUFFER\_Update)を MulticastQueue に蓄積しており、
Node はこのキューから画像データを取得し、画面を描画している。
LOST\_CHILD の検出方法はこの MulticastQueue を使用している。
ある一定時間 MulticastQueue から画像データが取得されない場合 Memory Over Flow を回避するために Timeout スレッドが用意されている。
Timeout を検知した際、Node との接続が切れたと判断する。

図\ref{fig:lostChild}は6台の Node が接続してる状態で Node3 が切断した場合の木の再構成を示している。

\begin{itemize}
    \item Node3 の切断を検知した Node1 が Root Node へ LOST\_CHILD メッセージを送信する(1: sendLostChild)。
    \item LOST\_CHILD メッセージを受け取った Root Node は nodeList から切断した Node を消し、最後尾の Node6 に切断した Node Number を割り当てる(2: updateNodeList)。
    \item Root Node は最後尾の Node6 に、切断した子 Node3 が接続していた Node1 に接続する様に CONNECT\_TO メッセージを送信する(3: send ConnectTo (Node1))。
    \item 最後尾の Node が子 Node を失った親 Node へ接続しに行く(4: connect (Node1))。
\end{itemize}

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/lostChild.pdf}
    \end{center}
    \caption{LOST\_CHILD を検知・再接続}
    \label{fig:lostChild}
\end{figure}

LOST\_CHILD によって、 切断された全ての Node を検知することができるため、 nodeList の更新が正しく行われる。
よって、新しく接続に来た Node を適切な場所に接続することが可能となる。

\newpage

\section{共有画面切り替え}
ゼミでは発表者が順々に入れ替わる。発表者が入れ替わる度に共有する画面の切り替えが必要となる。

画面の共有にプロジェクタを使用する場合、 発表者が変わる度にケーブルの抜き差しを行う必要がある。
その際に、ディスプレイ解像度を設定し直す必要が出たり、 接続不良が起こる等の煩わしい問題が生じることがある。

従来のVNCを使用する場合、 画面の切り替えの度に一旦VNCを終了し、発表者の VNC サーバーへと再接続を行う必要がある。

TreeVNC はユーザが VNC サーバーへの再接続を行うことなく、ビューアの Share Screen ボタンを押すことによって、配信者の切り替えを行うことができる。

TreeVNC の Root Node は配信者の VNC サーバーと通信を行っている。
VNC サーバーから画面データを受信し、そのデータを 子 Node へと送信している。
配信者切り替え時に Share Screen ボタンが押されると、 SERVER\_CHANGE\_REQUEST メッセージに Node 番号やディスプレイ情報 を付加し、Root Node に送信する。
SERVER\_CHANGE\_REQUEST メッセージを受け取った Root Node は配信を行う Node の VNC サーバーと通信を始める。
この切り替え動作は別のスレッドを生成して行うため、 切り替え作業が終了したときに現在配信している画面が切り替わる。

そのため TreeVNC は配信者切り替えの度に VNC を終了し、再接続する必要がない。
更にプロジェクタ等も使用しないため、ケーブルの差し替えも行わずとも画面配信を行うことが出来

\newpage

\section{表示画面サイズの調整}
配信側 PC によって配信される画面サイズが変化する。配信側と Node で画面サイズに差がある場合、画面に入りきらない、表示画面が小さすぎる等の問題が生じる。

TreeVNC では ビューワに fit screen ボタンを設置することでこの問題を解決している。
fit screen ボタンが押されると PC の画面サイズに合わせてフルサイズで拡大・縮小する。

\section{複数のネットワークの対応}
TreeVNC は Root Node が複数のネットワークに接続している場合、 図\ref{fig:multinetworktree}の様に、ネットワーク別に木構造を形成する。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/multiNetworkTree}
    \end{center}
    \caption{Multi Network Tree}
    \label{fig:multinetworktree}
\end{figure}

TreeVNC は Root Node が TreeManager というオブジェクトを持っている。
TreeManager は TreeVNC の接続部分を管理している。
TreeManager では木構造を管理する nodeList が生成される。
この nodeList を元に、新しい Node の接続や、切断検出時の接続の切り替え等を行う。

Root Node の保持しているネットワーク毎にTreeManager を生成する。
新しい Node が接続してきた際、 interfaces から Node のネットワークと一致する TreeManager を取得し、 Node 接続の処理を任せる。

\chapter{NAT 対応}
% NAT の説明がいる
% 基本的にグローバルip は複数のインタフェース
\section{NAT}
NAT(Network Address Translation) は ローカルなネットワークではプライベートIPアドレスを設定し、外のネットワークへ接続するときにグローバルIPアドレスに変換する技術のことである。 
また、NAT に変換にポート番号を付け加えることで1つのグローバルIPアドレスで複数のホスト間の通信も可能となる。
この変換はNAPT(Network Address Ports Translator) と呼ばれる
% NAT があるとTreeVNCがどうこまるのか
% マルチキャストが送られないので TreeVNC が見つからない アドレスが重複するなど
\section{TreeVNC での NAT の問題点}
TreeVNC は NAT の変換を経由した通信を行う場合様々な問題が発生する。

まず、Multicast 通信を行うことが出来ないという点である。 Multicast は同一ネットワーク内のマルチキャストアドレスを持っている端末に対してデータを送信することである。
TreeVNC は Root Node を探す際に FIND\_ROOT メッセージをMulticastで送信する。
しかし、NAT を越えたネットワークは同一ネットワークではないので、Root Node を探すことができない。

また、Root Node の木構造を管理しているnodeList に NAT を越えたネットワークのアドレスを追加していくとIPアドレスが重複する可能性があるため、通常の TreeVNC の構成では NATを越えたネットワークからの接続を行うことが出来ない。

\section{Direct Connection}
遠隔地からでもゼミや授業に参加できるよう、 NATを越えたネットワークから TreeVNC への接続を可能\cite{parusu:2016a}にした。

図\ref{fig:directConnection} にNATを越えたネットワークからの接続を示す。
別ネットワークからTreeVNCに参加する際、 直接配信側のネットワークの Root Node に接続を行う。
この接続を Direct Connection と呼ぶ。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/directConnection.pdf}
        \caption{Direct Connection}
        \label{fig:directConnection}
    \end{center}
\end{figure}

\newpage

\section{Direct Connectionでの木構造}
Direct Connection した Node はそのネットワークの Root Node になり、接続先である TreeVNC の nodeList に追加されない。
つまり、ネットワーク毎に木構造をもつことになる。

新しく接続する Node は図\ref{fig:directConnectionTree}のようにそのネットワークの Root Node に FIND\_ROOT メッセージを送信し、接続処理を行う。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/directConnectionTree.pdf}
        \caption{新しい Node の接続}
        \label{fig:directConnectionTree}
    \end{center}
\end{figure}

配信側の Root Node はDirect Connection で接続された Node に対して通常の子 Node と同じように FRAMEBUFFER\_UPDATE メッセージで画像データを送信する。
FRAMEBUFFER\_UPDATE メッセージを受けった Root Node はそのネットワークの Node に対して FRAMEBUFFER\_UPDATE メッセージを送信する。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/directConnectionFrameBuffer.pdf}
        \caption{NATを越えたネットワークへの画面配信}
        \label{fig:directConnectionFrameBuffer}
    \end{center}
\end{figure}

\section{NATを越えた共有画面切り替え}
図\ref{fig:directConnectionServerChange} は Direct Connection での画面切り替えの実装案である。
まず Direct Connection した ネットワークのクライアントから SERVER\_CHANGE\_REQUEST メッセージが送信される。
SERVER\_CHAGEN\_REQUEST メッセージを受け取った そのネットワークの Root Node は Direct Connection した先の Root Node へ SERVER\_CHANGE\_REQUEST を -1 を付加して送信する。
-1 を送信することで、 受け取った Root Node は別のネットワークからの画面切り替え要求ということを判断することができる。
別ネットワークからの切り替え要求を受け取った Root Node は読み込み用と書き込み用のソケットを入れ替える。
ソケットを入れ替えることで、 切り替え要求した Root Node のデータを受け取ることが可能となる。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/directConnectionServerChange.pdf}
        \caption{NATを越えたネットワークでの画面切り替え}
        \label{fig:directConnectionServerChange}
    \end{center}
\end{figure}


図\ref{fig:directConnectionServerChange} の実装案ではなく、画面切り替えが起こったネットワークに対して繋がっているネットワークが DirectConnection をすることで 容易に実装することができる。 
だが、 NAT を越えた接続のため、再接続する際に接続先が見つからないという問題が発生する。
そのため接続状況を維持したまま送受信状態を入れ替える必要がある。

しかし、接続状態を維持したままの入れ替えは実装が複雑になっており、今回追加した Direct Connection ではNATを越えたネットワークの画面の配信を行うのみであり、 画面切り替えを行うことが出来ない。


\chapter{マルチディスプレイ対応}
\section{マルチディスプレイ時の問題点}
画面配信側の PC がマルチディスプレイの場合、 図\ref{fig:multiDisplay}のように VNC サーバーからは複数の画面全体の画像データが送信されてしまう。
授業やゼミ等でTreeVNCを使用する場合、複数画面の表示は必要ない。
\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.6]{./images/multiDisplay.pdf}
    \end{center}
    \caption{マルチディスプレイでの送信}
    \label{fig:multiDisplay}
\end{figure}

\section{ディスプレイの選択}
マルチディスプレイでの問題を解決するため、画面を共有する際にディスプレイを選択させ、画面共有を行う機能を追加した\cite{parusu:2016a}。

ディスプレイの情報は個々のクライアントでしか取得ができない。
そのため、配信側は画面の切り替えを行う際に、ディスプレイを選択し、そのディスプレイの左上と右下の座標を取得する。
その座標を Root Node への画面切り替えを要求する SERVER\_CHANGE\_REQUEST メッセージに付加させる。 
Root Node は 配信側の VNC サーバー に画像データを要求する FRAMEBUFFER\_UPDATE\_REPLY メッセージに送信された座標を付加する。 
VNC サーバーは要求された座標内の画像データを FRAMEBUFFER\_UPDATE メッセージで Root Node に送信する。 
これにより、一画面のみの表示が可能になる。

図\ref{fig:multidisplay} は Display1 のみを画面共有する例を示している。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.4]{./images/shareScreenToMultiDisplay.pdf}
    \end{center}
    \caption{マルチディスプレイへの対応}
    \label{fig:multidisplay}
\end{figure}


\chapter{共有画面切り替えの安定化}
% もうちょい細かく Tight VNC はシングルthread でやっていた
% ユーザーが途中でキャンセルされると辛い とかの図を入れると1章分あるか?
% protoclContext
% protocolContext とか connectionPresenter とかのクラスdiagramで書くと良い
% コード乗っけても問題ない
\section{画面切り替えの問題点}
TightVNC では VNC サーバーへの接続を 1つのスレッドで行っていた。
そのため、 Tree VNC でも画面切り替えを行う際 配信中の画面を停止した後に VNC サーバーへの接続を行っていた。サーバー
しかし、 切り替え先の VNC サーバーへの接続に時間がかかったり、 切り替え先のクライアントに共有確認した際にキャンセルすると TreeVNC が停止するという問題があった。

\section{切り替え用スレッドの生成}
そこで、 画面切り替えを行う際に新しく切り替え用のスレッドを生成し処理する変更を行った。
実際に切り替えのスレッドを生成している inhelitClients メソッドを Code \ref{src:inhelitClients} に示す。

inhelitClients(Code \ref{src:inhelitClients}) は 3行目でConnectionPresenterクラスを新しく作っている。
ConnectionPresenter クラスは切り替えに必要な情報や処理が入っているクラスである。

8〜13行目は新しくスレッドを生成して実行している。このスレッドでは ConnectionPresenter クラスの startVNCConnection メソッドを読んでいる。
\lstinputlisting[label=src:inhelitClients, caption=切り替え用スレッドの生成]{src/InhelitClients.java}


\section{切り替え用スレッドの動作}
図\ref{fig:serverChangeThread}は画面切り替えの際に切り替え用スレッドを用いたときの通信の流れである。
まず共有先の Node から切り替え用のSERVER\_CHANGE\_REQUEST メッセージが送信される。
メッセージを受け取った Root Node は 切り替え用のスレッドを生成し、切り替えの処理を任せて、現在の配信の続行する。
切り替え用のスレッドではまず切り替えに必要なデータの設定、 VNC サーバー への接続など通常の切り替え処理を実行する。
切り替えが完了した後に、 現在配信中の画面を停止し、画面の切替を行う。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/serverChangeThread.pdf}
    \end{center}
    \caption{切り替え用スレッドの動作}
    \label{fig:serverChangeThread}
\end{figure}


\chapter{各 Node へのエラー通知}

\section{Root Node へのエラーメッセージの表示}
TreeVNC には接続している各 Node へのエラーの通知を行うことが出来なかった。
そのため、 画面切り替えを行う際に切り替え先が VNC サーバーの共有設定をしていない場合 Root Node に接続エラーのダイアログが表示されるという実装になっており、切り替えを行った Node には一切通知されなかった。 

\section{ERROR\_ANNOUNCE メッセージ}
この問題を解決するために新しくERROR\_ANNOUNCE というメッセージを追加した。
図\ref{fig:errorAnnounce} は Node3 に対してエラー通知を行っている例を示している。
ERROR\_ANNOUNCE メッセージは Root Nodeから木構造を辿りながら末端の Node に通信を行うメッセージで、エラー通知したい Node の Node Nuber と エラー内容の文字列を付加して送信する。
付加した Node Number に一致する Node がメッセージを受け取ると、 付加されたエラーの文字列をダイアログで表示する。
エラー通知用のメッセージを追加することで、 各々のクライアントに対して通知を行うことが可能になった。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.5]{./images/errorAnnounce.pdf}
    \end{center}
    \caption{ERROR\_ANNOUNCE メッセージの挙動}
    \label{fig:errorAnnounce} 
\end{figure}

通知を行えるようになると、ユーザーに対して共有設定の方法などが簡単に通知することができる。

\chapter{TreeVNC の評価}
\section{画像データ伝達の遅延}
VNC サーバー から受信する画像データ、 TreeVNC で扱われるメッセージ通信は構成された木を伝って伝達される。
接続する人数が増える毎に木の段数は増えていく。 そこで Root Node から木の末端の Node までの画像データ伝達の遅延を検証する実験を行った。

\section{実験環境}
授業を受講している学生が TreeVNC を使用した状態で実験を行った。
TreeVNC には最大で17名が接続していた。

\section{メッセージを使用した実測}
TreeVNC を伝搬するメッセージに、CHECK\_DELAY, CHECK\_DELAY\_REPLYを追加した。
CHECK\_DELAY は Root Node から 末端の Node まで伝達するメッセージと画像データ、 CHECK\_DELAY\_REPLY は各 Node から Root Node まで伝達するメッセージである。

CHECK\_DELAY メッセージは送信時刻を付けて送信する。
Root Nodeから CHECK\_DELAY 送信し、末端の Node まで各 Node を伝いながら伝達して行く。

CHECK\_DELAY\_REPLY は CHECK\_DELAY から受け取った送信時刻をそのままに、 画像データのサイズを付けて送信する。
CHECK\_DELAY を受け取った各 Node は CHECK\_DELAY\_REPLY を接続している親 Node に送信する。

CHECK\_DELAY\_REPLY を受け取った Root Node はメッセージと画像データの伝達にどれだけの時間がかかったかを計算する。
データ計算方法を以下の Code \ref{calc}に記述する。 この変数 time は CHECK\_DELAY\_REPLY に付いている CHEKC\_DELAY の送信時刻である。

\begin{lstlisting}[label=calc, caption=遅延時間の計算方法]
Long delay = System.currentTimeMillis() - time;
\end{lstlisting}

\section{結果}
バイナリツリーで木を構成した場合、 Node 数が17台だと深さが4となる。
各木構造の階層毎に、画像データの伝搬にかかった時間を測定した。

図\ref{fig:depth1}, \ref{fig:depth2}, \ref{fig:depth3}, \ref{fig:depth4}は遅延の分布を示した散布図である。
X軸はメッセージ伝達にかかった秒数(ms)、 Y軸は画像データのサイズ(Byte)である。

画像データの伝達はほぼ1秒以内に収まっているが、容量が小さい場合でも時間がかかる場合がある。
それはその送信の前に大容量の画像を送信した後の回線の Delay が残っているためだと考えられる。

また、深さ3で極端に遅い場合がある。
遅い原因として、1つの Node がボトルネックになっていることが判明している。
このような極端に遅い Node をそのまま木に配置した場合、その Node の子 Node 以下に影響を及ぼすおそれがある。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.7]{./images/depth1.eps}
    \end{center}
    \caption{データサイズと遅延の関係 : 深さ1}
    \label{fig:depth1}
\end{figure}

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.7]{./images/depth2.eps}
    \end{center}
    \caption{データサイズと遅延の関係 : 深さ2}
    \label{fig:depth2}
\end{figure}

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.7]{./images/depth3.eps}
    \end{center}
    \caption{データサイズと遅延の関係 : 深さ3}
    \label{fig:depth3}
\end{figure}

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.7]{./images/depth4.eps}
    \end{center}
    \caption{データサイズと遅延の関係 : 深さ4}
    \label{fig:depth4}
\end{figure}

\newpage

\section{ボトルネックになっている Node への対処}
画像データを受け取る時間が遅い Node をそのまま木構造に配置しているとその子 Node 以下に影響を及ぼす。
そのためネックになっている Node への対処が必要である。

ボトルネックになっている Node への対処として CHECK\_DELAY\_REPLAY メッセージを使用している。
図\ref{fig:fixTree}は 6台の Node が接続している状態で Node1 がネックになっている場合の木の再構成を示している。
CHECK\_DELAY\_REPLAY メッセージを受け取った Root Node はその Node がボトルネックなっているかの判断を行う。
ボトルネックになっているなら Root Node の nodeList からその Node を削除する。
削除した Node の場所には末端の Node を配置するように CONNECT\_TO メッセージを送信する。
nodeList から削除された Node は接続されたままなので、データの受信は行うが、 木構造には入らないため、ネックになっている Node の下に新しい Node が繋がることはない。
そのためネックになっている Node 以下に影響を及ばすことがない。

\begin{figure}[htbp]
    \begin{center}
        \includegraphics[scale=0.4]{./images/fixTree.pdf}
    \end{center}
    \caption{ボトルネックになっている Node への対処}
    \label{fig:fixTree}
\end{figure}

% 今後の課題

\chapter{結論}
\section{まとめ}
本研究では画面配信システム TreeVNC での NAT 対応、 リファクタリングによる機能改良、 TreeVNC の評価を行った。

NATを越えに対応した Direct Connection という接続方法を確立し実装した。
これにより、NAT を越えた別ネットワークのユーザーが TreeVNC に参加することが可能となった。

マルチディスプレイの場合に画面を選択して配信することが可能になった。

画面切り替えの際に切り替え用のスレッドを用意することでスムーズな画面切り替えが可能。

新しくメッセージを追加することでクライアントにエラー通知を行える様になった。

今回の画像データの遅延実験を行い、 ボトルネックになっているノードがあることがわかった。
また、ボトルネックになっているノードへの対処を行った。

\section{今後の課題}
Direct Conenction により、NAT を越えたの画面配信が可能となった。
しかし、 遠隔地からゼミや授業等に参加する場合は画面の表示のみではなく、 音声の配信も行いたい。
そのため音声配信機能の実装を行う必要がある。

今回実装したマルチディスプレイ選択の画面配信は PC の画面サイズに合わせてフルサイズで拡大・縮小する fit screen ボタンに対応しておらず、一画面のサイズの調節を行えない。
そのためマルチディスプレイの fit screen 機能を実装する必要がある。

現在の TreeVNC は TightVNC を直接編集しているため、コードが複雑になっている。 
そのため新しい機能を入れるにしてもリファクタリングから始める必要があった。 
当研究室で開発している分散フレームワーク Alice\cite{nozomi:2016a} の例題として記述された AliceVNC は TightVNC のコードの変更点を最小限に抑え、 複雑度も低いことがわかっている。 
そのため TreeVNC で今回追加した機能を AliceVNC で再設計することが望ましい。

%\section{Alice での実装}

% 参考文献
\def\line{−\hspace*{-.7zw}−}
\nocite{*}
\bibliographystyle{junsrt}
\bibliography{reference}


\chapter*{謝辞}
\thispagestyle{empty}

%基本的な内容は以下の通り.参考にしてみて下さい.
%厳密な決まりは無いので,個々人の文体でも構わない.
%GISゼミや英語ゼミに参加した人はその分も入れておく.
%順番は重要なので気を付けるように.(提出前に周りの人に確認してもらう.)

\hspace{1zw}本研究の遂行,また本論文の作成にあたり、御多忙にも関わらず終始懇切なる御指導と御教授を賜わりました河野真治准教授に深く感謝致します。

数々の貴重な御助言と細かな御配慮を戴いた小久保翔平さん、 徳森海斗さん、 比嘉健太さん並びに並列信頼研究室の皆様に深く感謝致します。

最後に、有意義な時間を共に過ごした情報工学科の学友、並びに物心両面で支えてくれた両親に深く感謝致します。

\begin{flushright}
    2016年 3月 \\ 伊波立樹
\end{flushright}

% 付録

\end{document}