RealVNC源码学习笔记 三
1、 RealVNC服务器端代码流程解析
RealVNC服务器端的main函数在winvnc模块的winvnc.cxx文件中,main函数很简单,该函数前面都是一些log信息设置,重点是构造VNCServerWin32对象后运行,该对象的run函数。VNCServerWin32构造函数如下:
VNCServerWin32::VNCServerWin32()
: command(NoCommand),commandSig(commandLock),
commandEvent(CreateEvent(0,TRUE, FALSE, 0)),
vncServer(CStr(ComputerName().buf), &desktop),
hostThread(0), runServer(false),isDesktopStarted(false),
httpServer(&vncServer),config(&sockMgr), trayIcon(0),
rfbSock(&sockMgr),httpSock(&sockMgr),
queryConnectDialog(0)
{
// Initialise the desktop
desktop.setStatusLocation(&isDesktopStarted);
// Initialise the VNC server
vncServer.setQueryConnectionHandler(this);
// Register the desktop's event tobe handled
//添加SDisplay事件到事件队列中(SDisplay继承自SDesktop)
sockMgr.addEvent(desktop.getUpdateEvent(), &desktop);
// Register the queued commandevent to be handled
//添加VNCServerWin32的事件到事件队列中
sockMgr.addEvent(commandEvent,this);
}
在VNCServerWin32的参数初始化列表中会构造RegConf类,RegConf构造函数中会添加一一个Regconf事件到事件队列中。这样经过VNCServerWin32构造函数就添加了三个事件到事件队列中。
VNCServerWin32的run函数代码如下:
int VNCServerWin32::run() {
//
{ Lock l(runLock);
hostThread = Thread::self();
runServer = true;
}
// - Create the tray icon (ifpossible)
//创建处理任务栏通知区VNC图标
trayIcon = newSTrayIconThread(*this, IDI_ICON, IDI_CONNECTED, IDR_TRAY);
// - Register for notification ofconfiguration changes
config.setCallback(this);
if (isServiceProcess())
config.setKey(HKEY_LOCAL_MACHINE, RegConfigPath);
else
config.setKey(HKEY_CURRENT_USER,RegConfigPath);
// - Set the address-changedhandler for the RFB socket
//通过层层调用,会创建两个监听tcp,分别监听5900(tcp port)和5800(http-port)端口
//并将套接字关联的事件加入到事件队列中
rfbSock.setAddressChangeNotifier(this);
DWORD result = 0;
try {
vlog.debug("Enteringmessage loop");
// - Run the server until we'retold to quit
MSG msg;
int result = 0;
//主循环
while (runServer) {
//获得消息,在getMessage中会调用消息(事件)的拥有这对消息(事件)进行处理
result =sockMgr.getMessage(&msg, NULL, 0, 0);
if (result < 0)