• 沒有找到結果。

Interaction Phase

第四章 VNC Client

5.3 Interaction Phase

它是以 big-endian 表示。Red-shift 表示從最大的位元算起,須位移幾個 bit 來取 得紅色的值。green- max, green-shift, blue-max, blue-shift 同理。

舉例,從一個給定的 pixel 值,取出紅色的成分: 值。而 colour map 是 Server 用 SetColour MapEntries 訊息來設定。

5.3 Interaction Phase

Handshaking Phase、Initialization Phase 結束後,隨即會進入 Client 和 Server 兩邊的訊息溝通,至於如何處理的部分,Server 是在 vncClientThread 初 始化完成後會進入一訊息處理迴圈,而 Client 則是 Viewer 程式建立程序完成後,

也會馬上進入訊息處理迴圈,在兩邊溝通的過程中,會有許許多多的訊息封包格 式,裡面各自蘊含了什麼功能和意義,在這節中會詳細介紹。此節共會分為兩小 節,5.3.1 是討論 Client 送給 Server 的訊息;5.3.2 節則是討論 Server 送給 Client 的訊息。如果要傳送非以上訊息,需要確定兩端都支援,否則 VNC 會忽略甚至 終止。

5.3.1 Client 送給 送給 送給 Server 的訊息 送給 的訊息 的訊息 的訊息

下表是 Protocol 中已訂定 Client 送給 Server 的訊息。

表 5-10.Client to Server messages Number Message Type

0 SetPixelFormat 2 SetEncodings

3 FramebufferUpdateRequest 4 KeyEvent

5 PointerEvent 6 ClientCutText

1. SetPixelFormat

此訊息是用來設定會在 FramebufferUpdate 訊息中用到的 pixel 格式值。如 果 Client 端沒有送出 SetPixelFormat 的訊息,Server 就一直依照初始化時,在 ServerInit 訊息中所設定的格式來編排 pixel 值!如果 true-colour- flag 是零值 (False),則表示 colour map 要被使用。即使 Server 之前有設定過對應表,只要 Client 送出 colour map 是空的,Server 必須立刻用 SetColourMapEntries 來設 定 colour map 的對應表(entry)。

表 5-12.PIXEL_FORMAT

表 5-11.SetPixelFormat

No. of bytes Type Description

1 U8 bits-per-pixel

1 U8 depth

1 U8 big-endian-flag

1 U8 true-colour-flag

2 U16 red-max

16 PIXEL_FORMAT pixel-format

2. SetEncodings: : : :

設定編碼種類,Server 會依照所設定的編碼來壓縮 pixel 資料。Client 一開 始會將預設偏好的編碼種類,照次序放在這個訊息裡傳給 Server (愈前面的愈優 先),而 Server 可以採納,也可以不理會這個提示。如果沒有明確定義編碼方式,

則 Server 會以 raw 的方式編碼 pixel 資料。除了原本的編碼,Client 可要求”

pseudo-encodings”,告訴 Server 它支援某種 protocol 的延伸。若 Server 不支 援,它會直接忽略。如果 Client 沒收到 Server 對 psudo-encoding 的確認,就知 道 Server 不支援。

表 5-13.SetEncodings No.of bytes Type [Value] Description 1 U8 2 Message-type

1 padding

2 U16 number-of-encodings

後面會接續 number-of-encodings 個編碼種類

表 5-14.Encoding-Type No.of bytes Type [Value] Description

4 S32 encoding-type

3. FramebufferUpdateRequest: : : :

用來告訴 Server,Client 想要 framebuffer 中的某一塊區塊,並以 x、y 座 標、長和寬來表示此面積!Server 會用 FramebufferUpdate 來回覆。

表 5-15.FramebufferUpdateRequest No. of bytes Type [Value] Description

Server 會假設 Client 保留 Framebuffer 的所有部分,所以一般來說,Server 只需要傳送有變動的區塊給 Client。但是,可能發生某些原因(如第一次的全螢幕 更新),Client 失去了 Framebuffer 的資料,則在發出 FramebufferUpdateRequest 訊息時,裡面的 incremental 就要設為零(False),Server 看到後會送出整個完整 的 Framebuffer 資料,而且不會使用 CopyRect encoding 傳送。如果 Client 沒有 喪失面積中任何的資料,則 incremental 會設為非零值(True),

Server 在收到 FramebufferUpdateRequest 訊息後,vncClientThread 會馬 上將 Update Flag 設為 TRUE,只有當畫面的某些區塊產生變動時,Server 才會 送出這些區塊的畫面資料。也因此,當 Client 發出 Request 後,如果 Server 部 分都沒發生變動,那麼 FramebufferUpdate 和 Request 之間可能會持續無限長的 時間。

4. KeyEvent: : : :

一個按鍵的按下或釋放。按鍵按下時 Down-flag 為非零值(True),按鍵釋放 down-flage 為零值(False)。

表 5-16.KeyEvent

No.of bytes Type [Value] Description 1 U8 4 message-type

1 U8 down-flag

2 padding

4 U32 key

表 5-17.一些常用的鍵 Key name Keysym value

BackSpace 0xff08

Tab 0xff09

Return or Enter 0xff0d

Escape 0xff1b

Insert 0xff63

Delete 0xffff

Home 0xff50

表 5-18.PointerEvent

6. ClientCutText: : : :

表示 Client 在它的剪貼簿中有新的東西。在行的結尾用新行(ASCII 的 0AH)代表,不需要歸位(ASCII 的 0DH)。不能傳 Latin-1 的字元以外的字。

Key name Keysym value

F1 0xffbe

Shift(left) 0xffe1 Shift(right) 0xffe2 Control(left) 0xffe3 Control(right) 0xffe4 Meta(left) 0xffe7 Meta(right) 0xffe8 Alt(left) 0xffe9 Alt(rigth) 0xffea

No. of bytes Type [Value] Description 1 U8 5 message-type

1 U8 button-mask

2 U16 x-position

2 U16 y-position

表 5-19. ClientCutText

0 FramebufferUpdate 1 SetColourMapEntries

2 Bell

3 ServerCutText

要使用非以上定義的訊息,Server 須收到 Client 回傳的確認訊息才可以.

1. FramebufferUpdate

它是 Server 用來回覆 FramebufferUpdateRequest。Framebufferupdate 包 含了一連串矩形畫面的壓縮資料,Client 收到後,會將他們一一解碼,並存進 Client 建立的 Framebuffer(初始化中的 Bitmap 記憶體)中。

表 5-22.Framebufferupdate No.of bytes Type [Value] Description

1 U8 0 message-type

1 padding

2 U16 Number-of-rectangles

Number Name

255 Anthony Liguori

254,127 VMWare

253 gii

後面跟著 number-of-rectangles 個矩形的 pixel 資料,每個矩形包含 表 5-23.每個矩形標頭資料

No.of bytes Type [Value] Description

2 U16 x-poisition

2 U16 y-position

2 U16 width

2 U16 height

4 S32 encoding-type

接著會再接著每個矩形畫面壓縮編碼後的資料。

2. SetColourMapEntries: : : :

當 Client 在送出 PIXEL_FORMAT 中的 True-Colour-Flag 為零值,即代表 要 使 用 調 色 盤 , Server 隨 即 會 送 出 這 個 SetColourMapEntries 訊 息 來 通 知 Client,傳過來的 Pixel 值應該對應到哪個 RGB 的強度,即所謂的調色盤。

表 5-24.SetColourMapEntries No. of bytes Type [Value] Description 1 U8 1 message-type

1 padding

2 U16 first-colour

2 U16 number-of-colours

後面會跟著 number-of-colours 個 colour 資料

表 5-25.對應 Colour 的 RGB 值

4. ServerCutText: : : :

表示 Server 在它的剪貼簿中有新的東西。在行的結尾用換行(ASCII 的 0AH) 代表,不需要歸位(ASCII 的 0DH)。不能傳 Latin-1 的字元以外的字。

表 5-27.ServerCutText

No.of bytes Type [Value] Description 1 U8 6 message-type

3 padding

4 U32 length

length U8 array text

5. rfbEnableExtensionRequest: : : :

這個延伸訊息是給 Client 和 Server 都有設定時用的,但其他版本的 VNC 可 能不支援,因此雙方都要確認是否有溝通好格式。

5.4 VNC 內建壓縮方法和資料封包 內建壓縮方法和資料封包 內建壓縮方法和資料封包 內建壓縮方法和資料封包

Server 會以 Framebuffer update 訊息,來傳送畫面更新,訊息前面會記載著這 個它承載了幾個矩形,和一連串矩形的標頭和編碼資料,這一小節,就是要來說 明解開這些矩形的標頭檔後,後續編碼資料的封包和格式,這些壓縮方法分別是 RAW、CopyRect、RRE、Hextile、和 ZRLE。

表 5-28.壓縮種類

-223 DesktopSize pseudo-encoding

在圖形傳輸時,根據不同的網路頻寬、Client/Server 處理資料的速度,VNC Protocol 提供了多種編碼方式,主要有 Raw、Copy-Rect、RRE、Hextile 以及 ZRLE,接下來說明這幾種編碼方式: width*height*bytesPerPixel PIXEL array pixels

2. CopyRect encoding::: :

將 framebuffer 中的圖形位置由一塊區域複製到另一塊區域,是一種簡單有 效率的方法,Client 端的 buffer 已經暫存了這塊區域的資料,Server 只要將 x、

y 的座標告知 Client,複製 buffer 中的資料,便可以在畫面中顯示出來,可以節 省網路頻寬。這樣的情形發生在移動桌面內的視窗時,由於視窗內的資料並沒有 改變,只需要改變顯示的區域,透過這樣的方法可以降低頻寬的使用。

表 5-30.CopyRect

No.of bytes Type [Value] Description

2 U16 src-x-position

2 U16 src-y-position

3. RRE::::

這種編碼方式是將同樣的 pixel 壓縮成單一數值重複計算,在 VNC 中實現的 方法就是將要傳送的矩型區域中的顏色資訊,找出分布最多的顏色當做背景色,

然後根據其他顏色的分布定義出多個子區域(Sub-rectangle)並記錄該區域的顏

色、位置以及大小,如下圖 33。而 Client 只須畫一個矩形,填滿背景 pixel 值,

然後把其它的矩形對應到其位置上,即可復原!此方法用在面積大顏色單純的區 塊(例如:單色的桌布畫面),但不適合於背景複雜的區塊

表 5-31.RRE

後面接著 Number-of subrectangles 個子矩形結構 表 5-32.RRE 的子結構 No. of bytes Type [Value] Description

bytesPerPixel PIXEL Subrect-pixel-value

2 U16 x-position

2 U16 y-position

2 U16 width

2 U16 height

圖 5-1.RRE 4. Hextile:

Hextil 是 RRE 的一種變形。一個矩形區域以 tile 為單位,由左至右、由上 至下依序切割,每個 tile 為 16 x 16 pixels,如果一個矩形區域,寬不是 16 的倍 數那麼最後一個 tile 的高度就會窄一點,相同情形,如果高不能被 16 整除,那 麼最後一個 tile 的寬度就會短一點。每個 tile 可以使用 Raw 編碼或是 RRE 編碼。

No.of bytes Type Value] Description

4 U32 Number-of-subrectangles

bytesPerPixel PIXEL Background-pixel-value

每個 tile 有自己的背景顏色,如果其背景顏色和前一個 tile 的背景顏色一樣,就 不需要明確定義;另如果所有子矩形的 pixel 值都一樣,則整個 tile 只需要記錄 前景 pixel 一次,和背景 pixel 類似,前景 pixel 也可以從前面的 tile 取得。

圖 5-2.Hextile 編碼

所有資料是由照順序編碼的 tile 所組成的,每個 tile 都由 subencoding type byte 開始,也就是一些 bits 組成的遮罩。

表 5-33.subencoding 遮罩 No.of bytes Type [Value] Description

U8 subencoding-mask:

1 Raw

2 BackgroundSpecified 4 ForegroundSpecified 8 AnySubrects

1

16 SubrectsColoured

Raw:如果 Raw bit 被設定了,則其他的 bits 都無效;後面會跟著 width*height 個 pixel 值(width 和 height 是 tile 的寬和高)

BackgroundSpecified:如果被設定了,後面會跟著這個 tile 的背景 pixel 值

如果這個 bit 沒有被設定,那背景 pixel 值和目前最後面的 tile 一樣。但當出 現第一個不是用 raw 編碼的 tile,這個 bit 就必須被設定。

表 5-34.BackgroundSpecified No.of bytes Type Value] Description

bytesPerPixel PIXEL background-pixel-value

ForegroundSpecified:如果被設定了,後面會跟著這個 tile 所有子矩形的前 景 pixel 顏色。這個 bit 若被設定,則 SubrectsColoured bit 必須設為 0。

表 5-35.ForegroundSpecified No.of bytes Type [Value] Description

bytesPerPixel PIXEL foreground-pixel-value

AnySubrects:若設定的話,會跟著一個 byte,記錄著子矩形的數量 沒有設定的話,就沒有任何子矩形(換言之,整個 tile 只有背景的顏色)

表 5-36.AnySubrects No.of bytes Type [Value] Description

1 U8 number-of-subrectangles

SubrectsColoured:AnySubrects 設定的話,須處理每個子矩形的 pixel 值。

子矩形的定義如下:

表 5-37.SubrectsColoured No.of bytes Type [Value] Description

bytesPerPixel PIXEL subrect-pixel-value

1 U8 x-and-y-position

1 U8 width-and-height

位置和大小,被定在兩個 bytes 內,在 x-and-y-position 的前四個 bits 為 x 座標,後四個 bits 為 y 座標,而 width-and-height 的前四個 bits 為寬減 1,

後四個 bits 為高減 1 如果沒有設定的話,所有的子矩形都是同一個顏色(前 景的顏色),如果 ForegroundSpecified bit 沒有設定,那就和最後一個 tile 的前景顏色一樣。

5. ZRLE:

Zib Run-Length Encoding(ZRLE),是結合了 zlib 壓縮、titlng、調色盤 和 rub-length 編碼技術。傳輸的時候,矩形區域以 4 個 bytes 開始,緊接著是 zlib 壓縮資料,唯一的 zlib stream 傳送在 RFB protocol 連線上,因此 ZRLE 區域必 須精確的依序編碼和解碼。Zlib 資料在還沒解壓縮之前,代表了 64 x 64 個 pixels,由左到右、從上到下,類似於 hextile 切割方式,如果高和寬不是 64 的 整數倍,那麼最後一筆資料區域會小一點。

第六章

動畫面,並將這些畫面資料傳送給 Client,而 Client 只要接收這些資料並更新在 Viewer 視窗上,使用者就能夠得知 Server 的狀態並操控它,這在一般操作的使 用並無太大問題,因為畫面的變動範圍和頻率不大,所需要處理的資料量有限,

但當使用者播放視訊檔案時,此時估且不論 Frame 大小,在每一秒中畫面更新少 則 15、6 個 Frame,多則高達 30 個 Frame,可想而知,Server 處理這些頻繁變 動的畫面範圍,將耗掉相當可觀的時間和頻寬。

因此,為了避免需要傳輸這麼龐大的資料量,我們勢必要提出一些方法來因 應。在 VNC 原本內部就規範了幾個壓縮方法:Hextile、CoRRE、RRE、RAW(請 參閱第五章最後),但實際播放影片(長度 1 分 04 秒、672*272 24 bits、23.976FPS) 來測試所得到的結果卻相當不理想,可見得這些壓縮方式,對於像影片這樣劇烈 畫面變動的情況下,發揮不了太大作用,測試數據如下表。