TightVNC分析文档

TightVNC 源码分析和实现 TightVNC 源码分析和实现前言新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 前言 你好! 这是你第一次... 阅读详情

System Shell :
1.1 IActiveDesktop
    Allows a client program to manage the desktop items and wallpaper on a local computer.

#include 

IActiveDesktop* active_desktop = 0;
CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
IID_IActiveDesktop, (void**)&active_desktop);

1.2 SetProcessShutdownParameters
    The SetProcessShutdownParameters function sets shutdown parameters for the currently calling process. This function sets a shutdown order for a process relative to the other processes in the system.
// Set this process to be the last application to be shut down.
SetProcessShutdownParameters(0x100, 0);

1.3 One Instance Running by Mutex
    Use Win32 Mutex object to insure that only one instance is currently running in our OS.
const char mutexname [] = "WinVNC_Win32_Instance_Mutex";

BOOL vncInstHandler::Init()
{
// Create the named mutex
HANDLE mutex = CreateMutex(NULL, FALSE, mutexname);
if (mutex == NULL)
return FALSE;

// Check that the mutex didn't already exist
if (GetLastError() == ERROR_ALREADY_EXISTS)
return FALSE;

return TRUE;
}

1.4 sscanf
    Read formatted data from a string.
// Check the protocol version
int major, minor;
sscanf((char *)&protocol_ver, "RFB %03d.%03d/n", &major, &minor);

1.5 Kill Screen Saver
// How to kill the screen saver depends on the OS
switch (osversioninfo.dwPlatformId)
case VER_PLATFORM_WIN32_WINDOWS:
HWND hsswnd = FindWindow ("WindowsScreenSaverClass", NULL);
if (hsswnd != NULL)
PostMessage(hsswnd, WM_CLOSE, 0, 0);
break;

case VER_PLATFORM_WIN32_NT:
HDESK hDesk = OpenDesktop(
"Screen-saver",
0,
FALSE,
DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS
);
if (hDesk != NULL)
{
EnumDesktopWindows(hDesk, (WNDENUMPROC) &KillScreenSaverFunc, 0);
CloseDesktop(hDesk);
// Pause long enough for the screen-saver to close
//Sleep(2000);
// Reset the screen saver so it can run again
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDWININICHANGE);
}
break;
}

1.6 Disable Nagle Algorithm
    Nagle Algorithm主要是用于优化小数据包的发送,用于在IP栈中缓冲小数据包,积累一定数量的小数据包一起发送。这样可以减少系统发包的数 量,Nagle Algorithm实现时内部也有一个Timeout机制,但这个Timeout时间长度不能在外部设置。而且对每个IP栈的实现,这个Timeout Span 都有一个实现相关的值。
// Disable Nagle's algorithm
BOOL nodelayval = TRUE;
setsockopt(m_sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelayval, sizeof(BOOL));


Screen Capture :
2.1 Poll Schema
    Poll 方式就是最简单的一种方式了,也是大家在考虑截屏时最先想到一个解决方案。为取得系统的屏幕,poll方案每33ms轮询一次系统屏幕,将变化的部分添加 加到一个UpdateRegion中。为获取这些屏幕变化的Rect,系统还采取了一种优化Polling算法,将屏幕分为32*32 pixel的小矩形块,算法给出了一个各个矩形块轮询的Order:
const int pollingOrder[32] = {
0, 16, 8, 24, 4, 20, 12, 28,
10, 26, 18, 2, 22, 6, 30, 14,
1, 17, 9, 25, 7, 23, 15, 31,
19, 3, 27, 11, 29, 13, 5, 21
};
获取当前屏幕鼠标图像的思路:
第一步:获取屏幕鼠标的HCURSOR
    GetCursorPos获取屏 幕鼠标位置,然后WindowFromPoint获取鼠标的拥有者窗口,GetWindowThreadProcessId获取相关线程ID,比较该ID 和GetCurrentThreadId返回的ID,如果相同,通过GetCursor直接获取鼠标的HCURSOR;否则,通过 AttachThreadInput连接上目标线程的Input Mechanism,再调用GetCursor获取鼠标的HCURSOR。
第二步:获取HCURSOR的Bitmap
int :GetCursorSendBuffer(BYTE *pBuffer, int nSize)
{
....
ICONINFO IconInfo;
GetIconInfo(hcursor, &IconInfo);

BITMAP bmMask;
GetObject(IconInfo.hbmMask, sizeof(BITMAP), (LPVOID)&bmMask);
GetBitmapBits(IconInfo.hbmMask,bmMask.bmWidthBytes * bmMask.bmHeight, m_mBits);
....
}

现在有必要对HRGN操作相关API做一下介绍
GetRgnBox      获取HRGN的边界矩形
GetRegionData 可以将一个HRGN分解为一个RECT数组,见RGNDATA结构体说明
CombineRgn 对HRGN操作RGN_AND,RGN_COPY,RGN_DIFF,RGN_OR或是RGN_XOR


2.2 TightVNC
    TightVNC(Tight Virtual Network Computing)是一个远程桌面控制的开源软件,详情请参考 http://www.tightvnc.com.下载了TightVNC的代码,分析了一下其Server部分的代码, WinVNC下的文件很多,但我们按照它们各自的功能做一下划分,其结构如下:

KernelvncBuffer.cpp vncClient.cpp vncDesktop.cpp vncServer.cpp WinVNC.cpp
GUIvncAbout.cpp vncAcceptDialog.cpp vncAdvancedProperties.cpp vncConnDialog.cpp vncMenu.cpp vncProperties.cpp vncTimedMsgBox.cpp
Miscd3des.c Log.cpp MinMax.cpp RectList.cpp stdhdrs.cpp tableinitcmtemplate.cpp tableinittctemplate.cpp tabletranstemplate.cpp translate.cpp vncauth.c vncInstHandler.cpp vncKeymap.cpp vncRegion.cpp< vncService.cpp
NetworkVSocket.cpp vncSockConnect.cpp vncHTTPConnect.cpp rfbproto.h
EncodingvncEncodeCoRRE.cpp vncEncodeHexT.cpp vncEncoder.cpp vncEncodeRRE.cpp vncEncodeTight.cpp vncEncodeZlib.cpp vncEncodeZlibHex.cpp





其服务端的主要功能模块结构如下:
其核心框架就是四个类vncClient,vncServer,vncDesktop和vncBuffer.下面我就这四个类之间的联系和用途来作一下简单的分析:
vncServer:
    vncServer 主要是做如下的一些工作:容许vncClient动态的添加和删除;将本地vncDesktop对象内部状态的任何改变"传播"到各个客户端;传播客户端 的鼠标和键盘事件到本地的vncDesktop对象。同时,其还创建了vncSockConnect,vncCORBAConnect和 vncHTTPConnect来接受Socket,Corba和HTTP的连接。 vncServer为每个连接上来的客户端分配了一个ClientID(其实就是内部客户对象数组的Index),并且提供了对客户端管理的众多函数:

virtual void DisableClients(BOOL state);
virtual void KillClient(vncClientId client);
virtual void KillAuthClients();
virtual void KillUnauthClients();

virtual vncClient* GetClient(vncClientId clientid);
vncClientId AddClient(VSocket *socket, BOOL auth, BOOL shared);
virtual void RemoveClient(vncClientId client);
同时,vncServer还提供了对客户Teleport,Capability,KeyboardEnabled,PointerEnabled,Name,Authenticated属性的get/set方法。
下面我们来看一下vncServer对客户端连接上来和客户端认证成功这两个事件的处理流程:
vncServer::AddClient:
    首 先vncServer在其内部的vncClient *m_clientmap[MAX_CLIENTS]数组中为新连接上的客户端分配一个空闲的slot,并将其作为此客户的 clientID. 然后,为此连接分配一个vncClient对象,根据传递过来的参数,设置vncClient对象的相关属性,然后调用vncClient::Init方 法将vncServer的实例指针和 clientID传给vncClient实例。接着,m_clientmap[clientid] = client并将此用户加入vncServer的未认证用户链表。
vncServer::Authenticated(vncClientId clientid):
    首 先从未认证用户列表中根据clientid获取vncClient对象,并将其从unauth list 中删除。如果是vncServer的第一个用户,创建vncDesktop对象,并调用m_desktop->Init(this)来初始化该 vncDesktop对象。接下来,为这个用户分配一个vncBuffer *buffer = new vncBuffer(m_desktop);并通过调用vncClient::SetBuffer为vncClient设置这个Buffer,最后将此用 户添加到auth list中。
    vncServer提供了一个用户列表的操作接口,这些接口通过将vncServer的方法调用映射到对auth list中各个客户的同样的方法的函数调用,这些方法有:
virtual void TriggerUpdate();
virtual void UpdateRect(RECT &rect);
virtual void UpdateRegion(vncRegion ®ion);
virtual void CopyRect(RECT &dest, POINT &source);
virtual void UpdateMouse();
virtual void UpdateClipText(LPSTR text);
virtual void UpdatePalette();
vncDesktop:
    vncDesktop是 一个全局唯一的对象,根据注释,vncDesktop主要是处理从display buffer中获取数据;同时,它还利用RFBLib DLL为vncServer提供诸如鼠标移动和屏幕更新等信息。上面提到,vncServer在第一个用户连接上来时发现其m_desktop为空时就创 建一个vncDesktip对象,并调用 vncDesktop::Init(this)对其初始化.在vcnDesktop::Init的实现中我们发现其创建了一个 vncDesktopThread,vncDesktop的方法调用大部分都在这个vncDesktopThread里完成的.下面我们来分析一下这个线 程都做了些什么:
vncDesktopThread::run_undetached(void *arg):
    首 先调用vncDesktop::Startup初始化,vncDesktop对象(见vncDesktop::Startup),然后就是处理桌面消息, 调用 m_server->UpdateMouse()和m_server->UpdateRegion(rgncache) ,接下来调用vncServer::TriggerUpdate来发送屏幕更新到每个vncClient.然后就是处理 RFB_SCREEN_UPDATERFB_MOUSE_UPDATE这两个注册消息。

vncClient:
    vncClient做了数据发送的工作,在vncClient::SendUpdate函数的实现中,我们可以看到vncClient调用 SendRFBMsg首先发送 ,然后 SendCursorShapeUpdate发送鼠标形状更新, SendCursorPosUpdate发送鼠标Pos更新,发送 SendCopyRect,最后调用 SendRectangles发 送需要更新的矩形的相关数据。其实每个客户端vncClient在调用vncClient::Init初始化的时候都开了一个线程,客户端的行为基本上都 是在vncClientThread::run里完成的。该线程在跟客户端交互完成了认证,Pixel格式,Encoding算法等信息的协商后,就进入 一个loop循环开始接受和处理远程客户端发过来的 rfbSetPixelFormat,rfbSetEncodings,rfbFramebufferUpdateRequest,rfbKeyEvent,rfbPointerEvent,rfbClientCutText 消息。

vncBuffer:
    vncBuffer主要处理发送数据的Encoding工作,其提供了远程客户的本地视图,其主要是利用内部的vncDesktop指针来获取相关的数据。

Reference:
改进TightVNC 笔记 2010 4.2->4.8 这一星期里我对TightVNC 1.3.10作了改进.但愿以下内容对你的调试,或者了解tightVNC 运行机制有所帮助. 目标是: 溶入到网络会议系统, p2p 模式无客户端请求数据. 带宽要求越小越好.实时性要求不是太高.可应用于大规模的网络培训, 网络教学. 如 单服务器支持的基于p2p 的上W人的网络培训. 等情况. 目前我已经实现无连接驱动 阅读详情

相关推荐

Ubuntu 16.04图形化远程桌面部署:TightVNC+GNOME Flashback实战指南

VNC(Virtual Network Computing)是一种基于RFB协议的跨平台图形远程访问技术,其核心原理是通过X11服务器捕获或渲染桌面帧并编码传输。在Linux系统中,VNC服务需与显示管理器(如LightDM)、桌面会话(如GNOME Flashback)及X11认证机制深度协同,才能实现稳定、低延迟的图形交互。Ubuntu 16.04因使用较老的X.Org 1.18、LightDM 1.18.3和GNOME 3.18(ubuntu-2d会话),对TigerVNC、x11vnc等新版本兼容性

weixin_30642561的博客 739

tightVNC 源代码

tightVNC源代码 编译通过VS2008 SERVER端和 VIEWER端

Ubuntu 20.04 手动部署 TightVNC 远程桌面实战指南

VNC(Virtual Network Computing)是一种跨平台的远程图形桌面协议,基于RFB协议实现像素级屏幕传输与输入转发,原理上独立于显示管理器和桌面环境。其技术价值在于轻量、协议透明、兼容性强,尤其适合嵌入式Linux、边缘服务器及故障救援等对稳定性与可控性要求极高的场景。相比GNOME自带的RDP方案,VNC可绕过GDM3绑定、支持独立会话隔离、适配OpenGL硬件加速,并能通过SSH隧道保障通信安全。本文聚焦Ubuntu 20.04 LTS系统,详解TightVNC编译安装、xstart

weixin_30319153的博客 367

tightvnc-2.7.7 源码

tightvnc-2.7.7 源码 VS2010 下编译通过

ACRDABA

unit ACRDABA; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, rootg, DB, ADODB, frxClass, frxDBSet, ImgList, ComCtrls,   Buttons, Wwdbigrd,

laty_cathy的专栏 822

tightVNC远控源码分析v1.3

WinVNC模块: 一。WinMain函数 1.初始化VSocketSystem套接字,初始化化log为winvnc.log文件,转换命令行参数为小写,解析命令行参数。没有命令行参数则进入WinVNCAppMain。 在函数WinVNCAppMain中:设置进程为关机时最后关闭。创建全局锁,确定只有一个进程实例在运行。 2.vncServer初始化:初始化成员变量,清空密码。如果版本大于4...

研究源码的最底层,只持有正确的仓位 2661

基于Tight VNC的远程协助功能的实现

整体布局   在远程协助中,请求协助的一方称为被协助方,或者(远程协助)服务端;响应的一方称为协助方,或者(远程协助)客户端;这里命名被协助方为Cv,而协助方命名为Cs,中转服务器为Sr。   TightVNC是免费为个人和商业用途,提供有用的,完整的源代码,在管理,技术支持,教育和许多其他用途,跨平台,可用于Windows和Unix,Java客户端,包括与标准的VNC软件兼容,符合RF...

weixin_30412577的博客 880

TightVNC 2.8.11:(一)源码编译

环境: Windows 7 旗舰版 64位、Visual Studio 2015 专业版 资源获取: TightVNC:官网 TightVNC 2.8.11程序安装包:32位、64位 TightVNC 2.8.11 源码:C++ Visual Studio 2015 :专业版 Windwos 8 SDK: 下载 编译问题总结: 问题1:无法打开源文件 “winapifam...

chase_hung的博客 4424

TightVNC开发

熟悉代码结构研究 TightVNC 的源代码结构,理解各个模块的作用。重点关注server和viewer目录下的代码。修改功能根据您的需求修改代码。例如,您可能想要添加新的压缩算法、改进安全性特性或是实现特定的平台支持。使用调试工具来跟踪和解决潜在的错误。测试更改在不同的操作系统和网络环境中测试您的更改,确保它们按预期工作。可以使用单元测试框架(如 Google Test)来编写自动化测试。文档更新更新相关的文档以反映所做的更改。贡献回社区。

weixin_41850878的博客 3627

TightVNC分析文档(转)

Content List: System Shell IActiveDesktop SetProcessShutdownParameters One Instance Running by Mutex sscanf Kill ScreenSaver Dia

huangxb2002的专栏 990

UltraVNC(TightVNC、WinVNC)源码分析文档

Posted on 2005-10-10 09:56 Piccolo Goo 阅读(3248) 评论(1)  编辑 收藏                                      Content List: System Shell IActiveDesktop SetProcessShutdownParameters One Instance Ru

松狮 7467

tightvnc 源码分析

tightvnc 版本 2.7.10。

xiaobaoo的博客 1325

深入探究TightVNC服务端源码与Visual Studio开发实践

TightVNC,一款开源的远程控制软件,允许用户通过网络对计算机进行操作。它支持VNC(Virtual Network Computing)协议,提供了跨平台的远程桌面连接能力。TightVNC的核心功能之一是远程控制和桌面共享。该功能允许用户通过网络连接到另一台计算机,并能够查看和控制其桌面环境。功能实现的关键点在于:会话管理:跟踪和维护当前所有活跃的远程会话。事件同步:将用户的键盘和鼠标操作实时同步到远程机器。视频流:将远程机器的屏幕变化以压缩视频流的形式实时传输。

weixin_42513928的博客 965

TightVNC远程控制工具实战指南

VNC(Virtual Network Computing)是一种基于RFB(Remote FrameBuffer)协议的远程桌面控制技术,允许用户通过网络远程访问和操作另一台计算机的图形界面。其核心原理是通过服务器端截取屏幕图像并发送至客户端,同时将客户端的键盘与鼠标事件反向传回服务器端,实现远程交互。TightVNC作为VNC家族的重要分支,因其轻量高效、跨平台支持良好而广受青睐。

weixin_31776191的博客 1716

Windows下TightVNC Server Web服务源码分析

使用TightVNC一段时间后,一直好奇它是如何实现用浏览器访问服务器端,今天就分析一下它的技术原理。用任一浏览器访问一台服务器例如http://192.168.1.102:5800,等其加载完后查看网页源文件可以看到下面的HTML代码: TightVNC desktop [jujumao]                       www.T

wangluozhangleilei的专栏 3829
上一篇: select函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET使用说明
下一篇: Notepad++ RegExp Help
Gary@Tokyo
博客等级 码龄20年 315粉丝 78原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值