• 沒有找到結果。

第四章 VNC Client

4.2 VNC Client 運作流程 運作流程 運作流程 運作流程

4.2.1 Initialization

這小節所做的設定,都是為了後續運作所需,如建立和 Server 溝通的 Socket、雙方認定的 RFB Protocol、密碼認証、建立 Client 端的 Framebuffer 和 Viewer 視窗、互相傳送初始化訊息、設定 Encoding 和之後解封包會用到的許 多參數,這一連串運作後續會一一解釋說明。

圖 4-4.Initialization

●Connect()

此函數中會建立 Client 端的 TCP/IP 設定,並和 Server 做三方交握,之後取 得 Connect_Socket_id,後續要傳送和接收任何封包皆是透過此 Socket。

●SetSocketOptions()

設定 TCP/IP 的一些功能,這部分不是那麼重要,就不細談。

● NegotiateProtocolVersion()

一開始會由 Server 傳送 Protocol Version 給 Client,讓 Client 知道 Server 最高可以支援的 RFB Protocol 版本,而 Client 會接收此訊息並做判斷,之後回 傳訊息告知實際是用哪一個 protocol!為了使雙方都可以向下支援,它不會要求 高於 Server 的 protocol version。這部分在第五章有更詳細的說明。

● Authenticate()

在 Protocol Version 被決定後,Server 必須和 Client 溝通連線安全性的種類。

這部分在第五章有更詳細的說明。

●CreateDisplay()

因為 VNC Client 需要有一個視窗介面程式:VNCviewer,讓使用者看到 Server 的畫面並透過它操控 Server,因此,這邊即是建立一個視窗程式。在第二 章的 Win32 程式建立流程中,已初步講解它所需的幾個關鍵區塊,而這個 CreateDisplay()函數,即是其中最重要 InitWindow()的細節。

圖 4-5.CreateDisplay

上圖中是 Win32 視窗程式建立的過程,第一個紅框框宣告 WINDCLASS 的 基本設定,裡面較重要的是藍色框框,它定義了 Viewer 對應的訊息處理函數 WndProc,即所有發送給 Viewer 視窗的訊息,都會在這個函數中做處理,因此,

當使用者對此 Viewer 視窗敲擊鍵或滑鼠,OS 都會以訊息發送給 WndProc,它 收到後會將這些訊息轉成 RFB Protocol 定義的封包格式傳送給 Server,如何轉 換的這部分在 4.3 節中會完整說明。

宣告並設定 WNDCLASS 後,要透過 RegisterClass 將它註冊到 Windows 中,

將著要用 CreateWindow()函數將此 Viewer 程式建立起來,第一個參數即是上面 的 WINDCLASS name,第二個參數是 Viewer 視窗程式的名稱:“VNCviewer

“,後面的是它的 x、y 座標和高、寬度。最重要的是,CreateWindow()函數的 回傳值,m_hwnd,它是此 Viewer 視窗的 HWND,後續 OS 都是由這個 HWND 來和 Viewer 視窗打交道。到此,一個 Viewer 程式已建立完成,但因為目前沒有 任何 Server 的畫面資料,因此還不能將把 Viewer 程式秀在螢幕上。

●SendClientInit()

●ReadServerInit()

在 Server 溝通好版本、安全性種類、認證正確,即會進入初始化程序,Client 會先送 ClientInit 訊息給 Server,通知是否准許有其他 Client 同時存在。等 Server 收到設定完,會回傳 ServerInit 訊息,來知會 Client 目前 Server 的 Framebuffer 狀況!!這部分在第五章會再詳細說明。

●CreateLocalFramebuffer()

圖 4-6.CreateLocalFramebuffer()

接收完 ServerInit 訊息後,我們就取得 Server 的桌面狀態,因此在這個函 數,就要將 Viewer 視窗初步外框秀出。函數一開始第一個紅框框中,會建立和 Server 桌面相同大小的 Bitmap 記憶體,這邊建立 Bitmap 記憶體也是為了之後 能夠快速更新畫面,因為後續只要將畫面像素資料複製到此塊記憶體,再透過 BitBlt 函數即可更新變動區塊到螢幕。

第二塊紅框框是因為尚未取得 Server 的初始畫面,在此會使用 GDI 的函 式,先將 Viewer 視窗的工作區間背景設為灰色,並在要上面輸出“Please wait - initial screen loading“這串字。第三塊紅框框 InvalidateRect ()觸發後,OS 會偵測到無效區域產生,它會傳送 WM_PAINT 給 Viewer 的訊息處理函數 WndProc(),裡面會將剛剛設定的畫面秀在螢幕,如下圖。外面框框的名稱是 Server 的電腦名稱,背景是灰色,在左上角的位置印有 Please wait - initial screen loading“。

圖 4-7.Initial Viewer

●SetupPixelFormat()

這邊是設定 ServerInit 訊息中的 PIXEL_FORMAT 參數,將這些參數記錄 下來,在後續工作會用到。

●SetFormat And Encodings()

傳送 Client 目前螢幕的 PIXEL_FORMAT 給 Server,並將內部支援的編碼 格式,依使用者的優先順序排好,以 rfbSetEncodings 訊息傳送給 Server。

以上就是所有的 Initialization,這一連串的工作都是為了後續運作正常,接著下 一節要說明初始化後,Client 會接收 Server 送來哪些訊息。