WINVNC原始碼閱讀(六)

2021-06-20 12:42:41 字數 3067 閱讀 5381

vnc客戶端原始碼

windows版本的vnc客戶端原始碼閱讀筆記。

while (!hosts.empty())

跟進去cconnthread的構造類,

cconnthread::cconnthread(const char* hostorconfig_, bool isconfig_)

: thread("cconnthread"), hostorconfig(strdup(hostorconfig_)),

isconfig(isconfig_), sock(0), reverse(false)

其中lock l(mutex &)是乙個鎖,對該定義以後的操作加互斥,直到程式塊結束l被析構時呼叫~lock自動解鎖。cconnthread由

thread派生,跟進去thread的構造類,可以看到構造類裡面基於threadproc建立了乙個執行緒。執行緒建立後是掛起的。其中threadproc就是

關鍵執行緒。在完成父類thread的構造後,cconnthread的建構函式中把新建的執行緒插入執行緒表中,然後呼叫cconnthread::start()喚醒剛

建立的執行緒。

thread::thread(const char* name_) : name(strdup(name_ ? name_ : "unnamed")), sig(0), deleteafterrun(false)

thread::threadproc(lpvoid lpparameter) catch (rdr::exception& e)

bool deletethread = false;

if (deletethread)

delete thread;

return 0;

}thread::start()

}cconnthread中建立了乙個cconn類。cconn類繼承於cconnection類,是cconnection類的windows實現類。cconn初始化連線線程

後,呼叫processmsg()函式來處理訊息。

conn.initialise(sock, reverse);

while (!conn.isclosed())

...}

processmsg()是父類cconnection的乙個方法函式,收到的資訊依次是版本資訊,安全認證資訊,視窗初始化資訊,初始化完成

後,主要呼叫reader_->readmsg()來讀取與伺服器的資訊。

void cconnection::processmsg()

}對著rfb的協議文件來看,服務端的資訊型別如下:

number name

0 framebufferupdate

1 setcolourmapentries

2 bell

3 servercuttext

用的最多的是,framebufferupdate,其訊息格式如下:

no. of bytes type [value] description

1    u8 0 message-type

1      padding

2    u16    number-of-rectangles

幀快取更新消是以矩形為單位來傳輸更新資料的,緊接著更新包頭之後是個number-of-rectangles個矩形的資料,每個矩形可以

用不同的編碼來傳輸。每個矩形的描述如下(矩形描述之後接的就是實際的影象內容的對應的編碼資料):

no. of bytes type [value] description

2    u16    x-position

2    u16    y-position

2    u16    width

2    u16    height

4    s32    encoding-type

對著協議看**,很容易就可以理解處理流程。

void cmsgreaderv3::readmsg()

} else ;

nupdaterectsleft--;

if (nupdaterectsleft == 0) handler->framebufferupdateend();}}

vnc的核心就是分塊編碼傳輸顯示,下面的**就是讀取矩形資料的**。cmsgreader是乙個讀取並處理收到的訊息的類。

cmsgreader有個decoder指標陣列decoders。decoder是乙個解碼類,類中有方法對vnc服務端傳來不同編碼的矩形資料解碼。decoders保

存著各種編碼對應的解碼器。當訊息是矩形區域更新的時候,會呼叫decoders中對應的解碼器的decoder::readrect()來解碼。如果對應

的decoders陣列沒有儲存解碼器,就先呼叫decoder::createdecoder()來生成解碼器。

void cmsgreader::readrect(const rect& r, unsigned int encoding)

if (r.is_empty())

fprintf(stderr, "warning: zero size rect\n");

handler->beginrect(r, encoding);

if (encoding == encodingcopyrect) else

}decoders[encoding]->readrect(r, handler);

}handler->endrect(r, encoding);

}decoder類中有些**比較晦澀。

typedef decoder* (*decodercreatefntype)(cmsgreader*);

......

static decodercreatefntype createfns[encodingmax+1];

閱讀這段**需要對typedef了解比較好,下面這個**會有較大幫助。typedef的四個用途和兩個陷阱:

decodercreatefntype是乙個函式指標,指向的函式的引數是指向cmsgreader的指標,返回值是指向decoder的指標。

createfns是乙個靜態的指標陣列。每乙個成員用於生成乙個與序號對應的解碼器。createdecoder使用的就是createfns中對應的函式。

rpg ig active原始碼閱讀 六

今天還是主要看ig active reconstruction 昨天看了幾個通訊介面的檔案,今天看其他的 getig communit useinformationgain world representation raycaster.hpp world representation pinhole...

《原始碼閱讀》原始碼閱讀技巧,原始碼閱讀工具

檢視某個類的完整繼承關係 選中類的名稱,然後按f4 quick type hierarchy quick type hierarchy可以顯示出類的繼承結構,包括它的父類和子類 supertype hierarchy supertype hierarchy可以顯示出類的繼承和實現結構,包括它的父類和...

Spark常用函式(原始碼閱讀六)

原始碼層面整理下我們常用的操作rdd資料處理與分析的函式,從而能更好的應用於工作中。連線hbase,讀取hbase的過程,首先 如下 def tableinitbytime sc sparkcontext,tablename string,columns string,fromdate date,t...