WIKI 上的解釋(截錄一小部份)
VNC(Virtual Network Computing),為一種使用RFB協定的螢幕畫面分享及遠端操作軟體。VNC由Olivetti & Oracle研究室所開發,此研究室在1999年併入美國電話電報公司(AT&T)。AT&T於2002年中止了此研究室的運作,並把VNC以GPL釋出。
原來的AT&T版本已經不再使用,因為更多有重大改善的分支版本已經出現, 像是RealVNC, VNC tight 和UltraVNC, 他們具有全面的向後兼容。至少對於基本的遠程控制功能而言。 Real VNC 是當前最活躍和強大的主流應用。
上圖是VNC的運作概念,RFB Server,也就是所謂的被控端,傳送有變化的螢幕區塊到RFB Client端,然候RFB Client則傳送滑鼠,鍵盤指令過去。而RFB對Client硬體要求不高,它只是把傳送過來的區塊資料繪圖在螢幕上 ,而把變化的區塊計算、壓縮等等的工作都落在Server身上。
基本上區塊的內容並不是固定的大小,視不同的範圍以及壓縮方法不同可能有所改變。區塊內的內容會包含區塊內容(可能是經過壓縮運算或RAW)、區塊左上角的X、Y位置(相對於Server螢幕),區塊的長寬高。
關於畫面的更新機制,其實Server並不是一直傳送更動區塊給Client,而是由Client端所驅動。(The update protocol is demand-driven by the client.)這樣有一個好處,當遇到Client端硬體較弱或是網路很差時,可以在client己繪完圖後再要求更新,或是依網路情況調整更新速度,給予RFB協定一定程度的彈性。值得注意的是,Server可能會合併數個FrameUpdateRequest,然候只回傳一次畫面更新。
輸入的協定為標準的鍵盤以及滑鼠(支援滾輪,左、右鍵),當然你也可以用手寫,經過識別後再模擬成鍵盤事件傳送過去(需自行實作或現有的資源做開發,例如我在手寫皮上手寫個C,被識別後就當做我按下C這個鍵傳送出去)。
在區塊資料上其實支援了幾種方式(編碼),Client會提交所支援的數種方法供Server端選擇,Server端會選擇對Server端最有利的方式處理。(However if the client is able to cope equally with several different formats or encodings, it may choose one which is easier for the server to produce.)
當然您也可以自己實作編碼方式,只要Server端以及Client都實作支援自訂編碼即可。
-----------------------------------------------------------------------------------------------------------
像素格式常見有 8 位元的 colour map ,以及 16位元以及24位元的true colour 。
編碼的方式,主要有以下幾種,詳細在最後一節有說明。
1.Raw encoding
2.Copy Rectangle encoding
3. RRE encoding
4.Hextile encoding
資料來源 http://greatcreatcreate.blogspot.tw/2009/09/rfb-vnc.html
5. ZRLE encoding
資料來源 http://greatcreatcreate.blogspot.tw/2009/09/rfb-vnc.html
Pseudo Encodings
編碼資料中對於偽編碼(Pseudo Encodings),Client可以對Server要求“pesudoencoding”,宣告其本身支援這一類型的擴充協定;假若Server不支援”pseudo-encoding”則會略乎此編碼。該注意的是Client必需假設Server不支援這類的擴充,直到Client從Server取得真正完成擴充認證。
資料來源 http://greatcreatcreate.blogspot.tw/2009/09/rfb-vnc.html
下列圖表是各種VNC軟體對編碼的支援程度。可以注意到其實有些編碼方式並不在上述列表中,例如像tight, Ultra 等等,皆是後來分支新增的編碼方式。
Feature Matrix
資料來源 http://wiki.qemu.org/Google_Summer_of_Code_2010/VNC#RRE
RFB協定可以依任何可靠的定協傳送資料 (如TCP/IP),即使byte-streamor。正常來說RFB主要透過TCP/IP達成連線。完成一個RFB協定有三個步驟:第一步為「handshaking phase」,此階段主要是去同意協定的版本及使用的安全型態;第二步為「initialization phase」,即對Server與Client互相交換「ClientInit」及「ServerInit」的訊息。第三步為「normal protocol interaction」,Client將能夠傳送任何它想傳送的訊息,然後接受Server回傳的結果。
資料來源 http://greatcreatcreate.blogspot.tw/2009/09/rfb-vnc.html
Protocol Messages
首先我們先了解RFB中使用的資料型別,
U8, U16,U32 表示不帶正負號 8 ,16 ,32 bit
INT8, INT16, INT32 表示帶正負號 8 , 16 ,32 bit.
除了pixel本身的值以外,所以協定中用到的byte 皆使用big endian order
會有Byte order的問題主要在於當需要表現超過255的數字時,需要兩個以上的Byte。此時,究竟要以代表比較小的數字的byte先放,還是代表比較大的數字 先放呢?以小的數字的Byte先放的作法就稱為little-endian。反之,以大的數字的byte先放的就稱為big-endian。 例如下列4組2進制 表示10進制的66051, 最高位元組先存,則為big-endian ,
00000000 00000001 00000010 00000011
若存成下列這副模樣,則為little-endian
先 00000011 然後 00000010 然後 00000001 最後 00000000
資料來源 http://www.dev.idv.tw/mediawiki/index.php/%E5%90%84%E7%A8%AE%E7%B3%BB%E7%B5%B1%E7%9A%84Byte_order
http://jyhshin.pixnet.net/blog/post/26587992-big-endian-(%E5%A4%A7%E9%A0%AD%E6%B4%BE)%EF%BC%8Clittle-endian-(%E5%B0%8F%E9%A0%AD%E6%B4%BE)
RFB 從交握到開始傳送畫面的運作模式如下圖
協定版本
「Handshaking Phase」開始前,Server會傳送ProtocolVerstion的訊息給Client,好讓Client能夠知道Server端支援RFB的最高版本,隨而Client回應Server可使用的版本號碼(不一定與Server的版本號碼相同),正常來說,Client不該要求高於Server端RFB的版本。
ProtocolVersion message 內容是 12 bytes ASCII characters 格式為 "RFB xxx.yyy\n" ,XXX為主要版本號,而yyy為次要版本號。 目前有以下三種可能。
No. of Byte
|
Value
|
Remark
|
12
|
“RFB 003.003\n” (hex 52 46 42 20 30 30 33 2e 30 30 33 0a)
|
3.3
|
12
|
“RFB 003.007\n” (hex 52 46 42 20 30 30 33 2e 30 30 37 0a)
|
3.7
|
12
|
“RFB 003.008\n” (hex 52 46 42 20 30 30 33 2e 30 30 38 0a)
|
3.8
|
安全性
一定協定版本確認後,Client、Server在連線時,必需協議共同的安全性標準。假若Client支援的安全性協定有在Server列舉的安全性協定清單中,Client會回傳單一byte的訊息告知Server某安全性協定可被用於這次的連結。 在進行Handshaking Phase時,不論這一階段的連成是否成立,Server都會傳送一個字串通知Client,假若連線成立,RFB協定即進行下一階段──Initialization Phase.
假若安全性連線失敗,Server則傳送一則字串描述此異常,隨後終止連結。
Server 必須傳送所支援的安全性清單,格式如下表
No of bytes
|
Type [Value]
|
Description
|
1
number-of-security-types
|
U8
U8 array
|
number-of securitry-types
security-types
|
如果 number-of security-types 為零,或發生版本無法支援等等,則Server端必須回應一個理由給Client後中斷連線
No. of bytes
|
Type [Value]
|
Description
|
4
reson-length
|
U32
U8 array
|
reason-length
reason-string
|
下列是安全性認證的列表
Number
|
Name
|
0
|
Invalid
|
1
|
None
|
2
|
VNC Authenication
|
5
|
RA2
|
6
|
RA2ne
|
16
|
Tight
|
17
|
Ultra
|
18
|
TLS
|
19
|
VenCrypt
|
20
|
GTK-VNC SASL
|
21
|
MD5 has authentication
|
22
|
Colin Dean xvp
|
Client回應選擇認證類型
No. of bytes
|
Type [Value]
|
Description
|
1
|
U8
|
security-type
|
VNC認證
連線時,隨送傳送16位元的VNC認證,而協定資料不做加密的動作。Server會隨機產生一個16 byte的要求Client回應特定的訊息。Client依據Server傳送過來的16 byte編碼為金鑰,並加密回傳此金鑰以回應Server。而此更協定依據項些安全性協定的回應持續進行下去。
Server 16 byte 金鑰
No. of bytes
|
Type [Value]
|
Description
|
16
|
U8
|
challenge
|
Client回覆內容
No. of bytes
|
Type [Value]
|
Description
|
16
|
U8
|
response
|
Server回覆
No. of bytes
|
Type [Value]
|
Description
|
4
|
U32
|
status:
OK
failed
|
在3.8版開始,如果Client回覆的認證Server不接受,則亦回覆一個錯誤原因
No. of bytes
|
Type [Value]
|
Description
|
4
reson-length
|
U32
U8 array
|
reason-length
reason-string
|
當Client、Server建立安全性連結後,接著會進行初始化層段(initialsation phase)
這個階段,在Client傳送一個「ClientInit」,Server隨即會傳送「ServerInit」訊息。
ClientInit:
Client回應的訊息只有一個「shared-flag」參數,若值非「0」(true),則表式Server試著去持續共享桌面而不對其他的Client端做終止連線的動作,反之,若值為「0」(false),則表示終止其他連線,僅對某Client端提供桌面分享的服務。
No. of bytes
|
Type [Value]
|
Description
|
1
|
U8
|
shared-flag
|
ServerInit:
Server 接受ClientInit訊息後,會接著發送ServerInit訊息,此訊息會告知Client端Framebuffer的長、寬、像素格式以及此桌面相關名稱。
No. of bytes
|
Type [Value]
|
Description
|
2
|
U16
|
framebuffer-width
|
2
|
U16
|
framebuffer-height
|
16
|
PIXEL_FORMATR
|
server-pixel-format
|
4
|
U32
|
name-length
|
name-lenght
|
U8 array
|
name-string
|
PIXEL FOMAT
No. of bytes
|
Type [Value]
|
Description
|
Remark
|
1
|
U8
|
bit-per-pixel
|
只能是8,16,32
|
1
|
U8
|
depth
|
位元深度(<= big-per-pixel)
|
1
|
U8
|
big-endian-flag
|
是否為big endian
|
1
|
U8
|
true-color-flag
|
是否使用true - color
|
2
|
U16
|
red-max
|
紅色最大值
|
2
|
U16
|
blue-max
|
藍色最大值
|
2
|
U16
|
green-max
|
綠色最大值
|
1
|
U8
|
blue-shift
|
在一組位元中,藍色必須位移多少
|
1
|
U8
|
red-shift
|
在一組位元中,紅色必須位移多少
|
1
|
U8
|
blue-shif
|
在一組位元中,綠色必須位移多少
|
3
|
padding
|
資料來源 http://greatcreatcreate.blogspot.tw/2009/09/rfb-vnc.html
http://www.realvnc.com/docs/rfbproto.pdf
Client to server messages ( 由Client傳給Server的封包格式)
Client傳給Server的Message有以下幾種,下面會分別介紹各種Message的封包結構,Server依此表格Number做為識別封包是何種類型,才有辦法正確解毒(每一封Message的封包格式長度都不同)
Number
|
Name
|
Remark
|
0
|
SexPixelFormat
|
設定PixelFormat
|
2
|
SetEncodings
|
設定編碼
|
3
|
FramebufferUpdatReauest
|
要求更新畫面資訊
|
4
|
KeyEvent
|
鍵盤事件
|
5
|
PointVent
|
滑鼠事件
|
6
|
ClientCuText
|
剪貼簿
|
SetPixelFormat
No. of bytes
|
Type [Value]
|
Description
|
1
3
16
|
U8 0
PIXEL_FORMAT
|
message-type
padding
pixel-fromat
|
PIXEL_FORMAT
No. of bytes
|
Type [Value]
|
Description
|
Remark
|
1
|
U8
|
bit-per-pixel
|
只能是8,16,32
|
1
|
U8
|
depth
|
位元深度(<= big-per-pixel)
|
1
|
U8
|
big-endian-flag
|
是否為big endian
|
1
|
U8
|
true-color-flag
|
是否使用true - color
|
2
|
U16
|
red-max
|
紅色最大值
|
2
|
U16
|
blue-max
|
藍色最大值
|
2
|
U16
|
green-max
|
綠色最大值
|
1
|
U8
|
blue-shift
|
在一組位元中,藍色必須位移多少
|
1
|
U8
|
red-shift
|
在一組位元中,紅色必須位移多少
|
1
|
U8
|
blue-shif
|
在一組位元中,綠色必須位移多少
|
3
|
padding
|
SetEncodings
No. of bytes
|
Type [Value]
|
Description
|
1
1
2
|
U8 2
U16
|
message-type
padding
number-of-encodings
|
number-of-encodings repetitions
No. of bytes
|
Type [Value]
|
Description
|
4
|
S32
|
encoding-type
|
FramebufferUpdateRequest
No. of bytes
|
Type [Value]
|
Description
|
1
1
2
2
2
2
|
U8 3
U8
U16
U16
U16
U16
|
message-type
incremental
x-position
y-position
width
heigtht
|
在此值得注意的是,incremental這個值,如果你並未擁有或是遺失某一區塊的畫面資料時
你在呼叫FramebufferUpdateRequest 必須把incremental設為0 ,這樣Server才會傳送整塊的畫面過來,或incremental設為非零的值,Server傳來的可能是CopyRect encoding ,要你參照某一塊的頻色,以減輕網路傳送的資訊量。
KeyEvent
當您的鍵盤有輸入東西時,您可以透過key Evnet把您所輸入的內容傳輸過去
No. of bytes
|
Type [Value]
|
Description
|
1
1
2
4
|
U8 4
U8
U32
|
message-type
down-flag
padding
key
|
值得注意的是down-flag, 當某個鍵被按下時,down-flag為非0的值,當此鍵被釋放後,down-flag為
0值。以下是key所代表的值。 除了部份的功能鍵(F1~F12 ,CTRL ,ALT等等),都相同於ASCII CODE,下面列出功能鍵的碼。值得注意的是shift 鍵只有在被按下時才會傳送。
Key Name
|
Keysym value
|
BackSpace
|
0xff08
|
Tab
|
0xff09
|
Return or Enter
|
0xff0d
|
Esc
|
0xff1b
|
Insert
|
0xff63
|
Delete
|
0xffff
|
Home
|
0xff50
|
End
|
0xff57
|
Page Up
|
0xff55
|
Page Down
|
0xff56
|
Left
|
0xff51
|
Up
|
0xff52
|
Right
|
0xff53
|
Down
|
0xff54
|
F1
|
0xffbe
|
F2
|
0xffff
|
F3
|
0xffc0
|
F4
|
0xffc1
|
---
|
---
|
F12
|
0xffc9
|
Shift(left)
|
0xffe1
|
Shift(right)
|
0xff22
|
Control(left)
|
0xffe3
|
Control(right)
|
0xffe4
|
Meta(Left)
|
0xffe7
|
Meth(Right)
|
0xffe8
|
Alt(left)
|
0xffe9
|
Alt(right)
|
0xffea
|
PointerEvent
button-mask 是一個8bit位元組,支援了滑鼠8個按鈕,1表示按下 ,0表示此按鈕沒有被按下,
但預設button 1表示左鍵,button 2表示中鍵,button 3 表示右鍵,而滾輪的滾動則由button 4及button5表示,例如button4按下表示滾輪向上滾動,button5按下表示滾輸向下滾動。
No. of bytes
|
Type [Value]
|
Description
|
1
1
2
2
|
U8 5
U8
U16
U16
|
message-type
button-mask
x-position
y-position
|
ClientCutText
這東西就類似一個剪貼簿,在文字內容最後面必須要補一個AscII 10 ( 13免)
No. of bytes
|
Type [Value]
|
Description
|
1
3
4
length
|
U8 6
U32
U8 array
|
message-type
padding
length
text
|
相對於client,Server端傳給Client的訊號花樣就沒那麼多種了。
Number
|
Name
|
Remark
|
0
|
FramebufferUpdate
|
回傳畫面資料
|
1
|
SetColorMapEntries
|
設定頻色的對應(當client使用 colur map)
|
2
|
Bell
|
請Client端逼一聲
|
3
|
ServerCuText
|
Server端的剪貼簿
|
FramebufferUpdate
No. of bytes
|
Type [Value]
|
Description
|
1
3
2
|
U8 0
U16
|
message-type
padding
number-of-rectangles
|
No. of bytes
|
Type [Value]
|
Description
|
2
2
2
2
4
|
U16
U16
U16
U16
S32
|
x-position
y-position
width
height
encoding-type
|
如上圖所示,我們可以理解其實Server一次可能會傳N個rectangles給Client。
encoding-type 其實也是一個一個不同 種類編碼的封包,容我後面再一一詳細解說。
SetColourMapEntries
當Client端 colur-map 等於1時,表示使用頻色的映射 , 它和樓上的封包一樣,也是一列火車的型式,告訴Client端該怎樣傳送對應的頻色過來。
No. of bytes
|
Type [Value]
|
Description
|
1
1
2
2
|
U8 1
U16
U16
|
message-type
padding
first-colur
number-of-colours
|
No. of bytes
|
Type [Value]
|
Description
|
2
2
2
|
U16
U16
U16
|
red
green
blue
|
Bell
當收到此封包時, Client端會發出"逼"一聲。所以它不必帶任何其他的資料,只有一個單純的message-type。
最後是最重要的Encodings 封包格式,其實也就是不同種類的螢幕畫面區塊編碼型的封包。
首先是各種Encodings對應的代碼以及所代表的名稱,有一些Number其實是代表著參數的變化,例如tight options ,則表示使用tight 這個Encoding時,會用到的參數,則透過tight options來做參數傳遞,例如圖像的品質、 壓縮程度。
DesktopSize pseudo-encoding
No. of bytes
|
Type [Value]
|
Description
|
1
|
U8
|
message-type
|
ServerCutText
No. of bytes
|
Type [Value]
|
Description
|
1
3
4
length
|
U8 3
U32
U8 array
|
message-type
padding
length
text
|
最後是最重要的Encodings 封包格式,其實也就是不同種類的螢幕畫面區塊編碼型的封包。
首先是各種Encodings對應的代碼以及所代表的名稱,有一些Number其實是代表著參數的變化,例如tight options ,則表示使用tight 這個Encoding時,會用到的參數,則透過tight options來做參數傳遞,例如圖像的品質、 壓縮程度。
Number
|
Name
|
0
|
RAW
|
1
|
CopyRect
|
2
|
RRE
|
5
|
Hextile
|
16
|
ZRLE
|
-239
|
Cursor pseudo-encoding
|
-223
|
Cursor pseudo-encoding
|
4
|
CoRRE
|
6
|
zlib
|
7
|
tight
|
8
|
zlibhex
|
15
|
TRLE
|
17
|
Hitachi ZYWRLE
|
18
|
Adam Walling XZ
|
19
|
Adam Walling XZYW
|
-1 to -222
| |
-224 to -238
| |
-240 to -256
|
tight options
|
-257 to -272
|
Anthony Liguori
|
-273 to -304
|
VMWare
|
-305
|
gii
|
-306
|
popa
|
-307
|
Peter Astrand DesktopName
|
-308
|
Pierre Ossman ExtendedDesktopSize
|
-309
|
Colin Dean xvp
|
-310
|
OLIVE Call Control
|
-311
|
CursorWithAlpha
|
-412 to -512
|
TurboVNC fine-grained quality level
|
-763 to -768
|
TurboVNC subsampling level
|
0x574d5600 to 0x574d56ff
|
VMWare
|
Raw encoding
No. of bytes
|
Type [Value]
|
Description
|
width × height × bytesPerPixel
|
PIXEL array
|
pixels
|
最基本的編碼方式,也就是代表由左到右掃描出來的像素值。所有版本的RFB協定都能支援此編碼。
CopyRect encoding
No. of bytes
|
Type [Value]
|
Description
|
2
2
|
U16
U16
|
src-x-position
src-y-position
|
這就是編碼中的烤貝忍者卡卡西了,直接告訴你去抄那一點的位置。不過前提是要抄的那一點必須先有資料才行。
RRE encoding
RRE指rise-and-run-length,其基礎在於模擬一段的二維編碼。RRE編碼所包函的rectangle會以能夠被簡易的繪圖engines有效率而快速繪製的形式到達Client端。 RRE編碼的缺點在於無法適用於複雜的桌面,但仍能使用於某些狀況。RRE編碼的基礎在於分割某像素資料的rectangle成多個副屬的rectangle,每一個副屬的rectangle都包括了各別區塊的像素內容,而將這些副屬的rectangle組合後,將會得到原始的rectangel,這些最適的副屬區塊相對的容易被計算出來。這項編碼包括背景像素值,
資料來源 http://greatcreatcreate.blogspot.tw/2009/09/rfb-vnc.html
No. of bytes
|
Type [Value]
|
Description
|
4
bytesPerPixel
|
U32
Pixel
|
number-of-subrectangles
background-pixel-value
|
number-of-subrectangles
No. of bytes
|
Type [Value]
|
Description
|
bytesPerPixel
2
2
2
2
|
Pixel
U16
U16
U16
U16
|
subrect-pixel-value
x-position
y-position
width
height
|
資料來源 http://greatcreatcreate.blogspot.tw/2009/09/rfb-vnc.html
http://www.realvnc.com/docs/rfbproto.pdf
Hextile encoding
Hextile編碼為RRE的一種延伸,其將rectangle分成16 x 16的區塊,可令其大小為每邊區塊4 bit,而一個被化分出來的rectangle共16bit。每個rectangle由左上開始往右下計算,先左而右,由上至下,而編碼的內容都會依據先前的rectangel排列模式做排列。假若一個rectangle的寬度並非16的倍數,則最後一個rectangel在劃份後的寬度將會小於16。高度的原理同於寬度。 每個區塊不管以Raw編碼或是RRE編碼都會有背景像素值(background pixel),若背景像素的數值同於前一區塊,則不需特別設定至新的區塊中。另一個狀況:若傳送資料是以Raw編碼,背景像素值則不需要做任何設定。假若所有的副屬區塊(subretangle)都擁有相同的背景像素值,可當做整個區塊的前景顏色像素值,僅做一次性的設定;前景像素可同於背景像素的指定方式,其不需特別設定至區塊中,可從前一個區塊中取得。假若先前的區塊是Raw或是SubrectColored的設定,當下的區塊就不會特別前景像素設定至當下的區塊中,但會以AnySubrects從前一區塊取得前景像素(假定前一區塊已經從更前面的區塊取得前景像素值)。
No. of bytes
|
Type [Value]
|
Description
|
1
|
U8
1
2
4
8
16
|
subencoding-mask:
Raw
BackgroundSpecified
ForegroundSpecified
AnySubrects
SubrectsColoured
|
BackgroundSpecified
假如subencoding-mask中的第1個位元設為1 ,則會帶有下列的背景值。
No. of bytes
|
Type [Value]
|
Description
|
bytesPerPixel
|
bytesPerPixel
|
background-pixel-value
|
ForegroundSpecified
假如subencoding-mask中的第2個位元設為1 ,則會帶有下列的前景值。
No. of bytes
|
Type [Value]
|
Description
|
bytesPerPixel
|
bytesPerPixel
|
foreground-pixel-value
|
AnySubrects
假如subencoding-mask中的第3個位元設為1 ,則會帶有下列的subrectangles數量值。
假如subencoding-mask中的第3個位元設為0 ,則整塊區域都是背景色。
No. of bytes
|
Type [Value]
|
Description
|
1
|
U8
|
number-of-subrectangles
|
SubrectsColoured
假如subencoding-mask中的第4個位元設為1 , 則每一個subrectangle的值,由下列資料型態表示。
No. of bytes
|
Type [Value]
|
Description
|
bytesPerPixel
1
1
|
PIXEL
U8
U8
|
subrect-pixel-value
x-and-y-position
width-and-height
|
假如subencoding-mask中的第4個位元設為0 ,且第3個位元設為1,則區域皆為前景色。
假如subencoding-mask中的第4個位元設為0 ,且第3個位元設為0,則區域皆為前景色。
No. of bytes
|
Type [Value]
|
Description
|
1
1
|
U8
U8
|
x-and-y-position
width-and-height
|
每一個subrectangle 由2個byte來做定義,x,y座標以及長寬,第1個byte的最高4個位元表示X座標,較低的4個位元表示Y座標,第2個byte最高4個位元表示寬度,較低4個位元表示高度.
ZRLE encoding
ZRLE代表的是Zlib1 Run-Length Encoding,擁有Z-lib的壓縮、劃分區塊的能力。在傳送的序列資料中,每個區塊由4 byte長的標頭開始,隨後接著由z-lib壓縮的資料。每個單z-lib序列物件主都會在RFB協定的連結中產生作用,所以編碼、解碼需定訂嚴格的順序。 Z-Lib的資料在解壓後,會產生64 x 64的區塊,其值由左至右、由上至下排列(同於Hextile),若資料的長寬bit數不是64的倍數,則最後一個區塊的長寬將會小於64 bit。 ZRLE利用CPIXEL(compressed pixel)技術,這方法同於一般的像素格式,其中所有的bit由(r,g,b)構成,不管(r,g,b)強度為何,true-colour-flag的值不會是0,bitperpixel的值是32,depth值會在24以下。ZRLE中,一個CPIXEL只會有3 byte的長度,亦可能包函最低顯著或最高顯著的(r,g,b)值。bytePerCPixel為ZRLE中CPIXEL的bytes數。 每個區塊以subbencoding type byte開始,假若區塊編碼的起始byte有做過任何設定,則代表此區塊已運行過或是已被清除等等。區塊最底部的7個位元指定著色的範圍,0代表沒有做任何著色;1代表區塊使用單一色系,2~127表示區塊共使用了多少的顏色。
資料來源 http://greatcreatcreate.blogspot.tw/2009/09/rfb-vnc.html
No. of bytes
|
Type [Value]
|
Description
|
4
length
|
U32
U8 array
|
length
zlibData
|
CPIXEL
Raw pixel data. width × height pixel values follow (where width and height
are the width and height of the tile):
No. of bytes
|
Type [Value]
|
Description
|
width × height × bytesPerCPixel C
|
CPIXEL array
|
pixels
|
1 - A solid tile consisting of a single colour. The pixel value follows:
No. of bytes
|
Type [Value]
|
Description
|
bytesPerCPixel C
|
CPIXEL
|
pixelV alue
|
2 to 16 - Packed palette types. Followed by the palette, consisting of paletteSize(=subencoding) pixel values. Then the packed pixels follow, each pixel represented as a bit field yielding an index into the palette (0 meaning the first paletteentry). For paletteSize 2, a 1-bit field is used, for paletteSize 3 or 4 a 2-bitfield is used and for paletteSize from 5 to 16 a 4-bit field is used. The bit fields are packed into bytes, the most significant bits representing the leftmost pixel (i.e. big endian). For tiles not a multiple of 8, 4 or 2 pixels wide (as appropriate), padding bits are used to align each row to an exact number of bytes.
No. of bytes
|
Type [Value]
|
Description
|
paletteSize × bytesPerCPixel
m
|
CPIXEL array
U8 array
|
palette
packedPixels
|
Cursor pseudo-encoding
簡單講就是Clinet要求Server回傳滑鼠游標圖案,讓Clinet自己畫在Client端畫面上。
Client若對Server發送這一則指令,即表示Client將有能力在本地端劃出server mouse的位置,這能夠在慢速的連線中明顯提升畫面呈現的效果。Server傳送FreamebufferUpdate時,會同時在Cursor pseudo-encoding設定pesudo-rectangle的內容回應Client的更新要求。pesudo-rectangle的內容包函x-position及y-position,其指出server端Cursor的位置,而width、height分別為Cursor的像素,並依據bitmask來設定資料的內容(所謂的bitmask,其內容主要是由左向右、由上至下對像素值做線性排列。
資料來源 http://greatcreatcreate.blogspot.tw/2009/09/rfb-vnc.html
No. of bytes
|
Type [Value]
|
Description
|
width × height × bytesPerPixel
floor((width + 7)/8) ∗ height
|
PIXEL array
U8 array
|
cursor-pixels
bitmask
|
DesktopSize pseudo-encoding
Client端對Server請求DesktopSize pseudo-encoding以告知本地端可應付Framebuffer中width、height值變動的狀況。Server通常會將這一個pseudo-rectangle設定至最後一個Framebuffer資料的DesktopSize pseudo-encoding中,而此項目中pesudo-rectangle的x-position及y-position會被乎略,width及height值會告知新的Framebuffer大小。
資料來源 http://greatcreatcreate.blogspot.tw/2009/09/rfb-vnc.html
沒有留言:
張貼留言