vnc安装说明

时间:2024.5.13

1.检测VNC是否安装

输入命令:rpm -q vnc-server,返回信息如下:

[root@wasServer ~]# rpm -q vnc-server

vnc-server-4.1.2-14.el5_3.1

已安装。

如果未安装,可用如下命令安装:

rpm -ivh /mnt/Server/vnc-server-4.1.2-9.el5.x86_64.rpm

2.设置 vncserver 开机自启动 # chkconfig vncserver on

3.启动VNC服务

# /etc/init.d/vncserver start /启动

4.启动vnc窗口1并设置密码为:

[root@testdb ~]# vncserver :1

password:

vnc#@!

3.修改配置文件,使其在 VNC 登录时调出图形界面。

# vi /root/.vnc/xstartup

#!/bin/sh

# Uncomment the following two lines for normal desktop: # unset SESSION_MANAGER # exec /etc/X11/xinit/xinitrc

[ ‐x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup

[ ‐r $HOME/.Xresources ] && xrdb $HOME/.Xresources

xsetroot ‐solid grey

vncconfig ‐iconic &

xterm ‐geometry 80x24+10+10 ‐ls ‐title "$VNCDESKTOP Desktop" &

#twm & //注释该行

gnome-session & /添加该行

保存退出后 需重新启动 vncserver服务使其生效,并杀掉启动的VNC第一个session。 vncserver -kill :1

重新启动vnc窗口1:vncserver :1,OK

4.VNC服务使用的端口号与桌面号的关系 -------------------------------------------------------------

VNC使用TCP端口从5900开始:

桌面号为“1” ---- 端口号为5901

桌面号为“2” ---- 端口号为5902

桌面号为“3” ---- 端口号为5903

基于Java的VNC客户程序Web服务TCP端口从5800开始,也是与桌面号相关,对应关系如下

桌面号为“1” ---- 端口号为5801

桌面号为“2” ---- 端口号为5802

桌面号为“3” ---- 端口号为5803

5.测试VNC服务是否通过了。

10.16.255.132:5901

第一种方法是使用VNC Viewer软件登陆测试,操作流程如下

启动VNC Viewer软件 --> Server输入“192.168.0.3:1” --> 点击“OK” --> Password输入登陆密码 --> 点击“OK”登陆到X-Window图形桌面环境 --> 测试成功

第二种方法是使用Web浏览器(如Firefox,IE,Safari)登陆测试,防火墙限制。


第二篇:vnc代码


vnc

win-hook + event-simulate + gdi-bitmap-capture(delay send) + libjpeg + socket

*******************************************************************************************************************

VNC的图像更新机制核心为,桌面区域更新记录策略和更新区域通知策略。

桌面更新区域记录主要是通过hooks记录桌面上变化的矩形区域,

只记录更新的矩形区不记录具体更新的数据。

更新区域记录步骤大致如下:

1.wm_hooks截获桌面变化的相关消息,并转化为自定义的消息发送给WMHooksThread线程处理。

2. WMHooksThread 中用SimpleUpdateTracker new_changes记录新的更新区域.

3.把SimpleUpdateTracker new_changes更新拷贝到SDisplay中。

4.每次要发送桌面更新的时候,把SDisplay中记录的更新区域传给VNCServerST 对象中。 更新区域的通知主要有poll和push两种机制。push是服务器每隔10ms检查有没有更新,如果有更新则主动把更新推送给客户端,

poll机制则是客户端主动请求更新,客户端通过发送framebufferupdate请求某一个区域更新,服务器处理该消息发送相应的更新。

********************************************************************************************************************

详细分析如下:

1.Wm_hooks截获消息并转化为自定义的消息发送给WMHooksThread线程处理。

Wm_hooks自定义的消息:

UINT WM_HK_WindowChanged = RegisterWindowMessage(_T("RFB.WM_Hooks.WindowChanged"));

UINT WM_HK_WindowClientAreaChanged = UINT WM_HK_WindowBorderChanged = RegisterWindowMessage(_T("RFB.WM_Hooks.WindowBorderChanged"));

UINT WM_HK_RectangleChanged = RegisterWindowMessage(_T("RFB.WM_Hooks.RectangleChanged"));

UINT WM_HK_CursorChanged = RegisterWindowMessage(_T("RFB.WM_Hooks.CursorChanged"));

钩子截获到消息以后,把它转化为自定义的消息,然后发送给WMHooksThread线程处理,消息转化如下:

边框更新消息:WM_NCPAINT,WM_NCACTIVATE

客户区域更新消息:BM_SETCHECK, BM_SETSTATE,EM_SETSEL,WM_CHAR,WM_ENABLE,WM_KEYUP,WM_LBUTTONUP,WM_MBUTTONUP,

WM_PALETTECHANGED,WM_RBUTTONUP,WM_SYSCOLORCHANGE,WM_SETTEXT。

窗口改变消息:WM_HSCROLL,WM_VSCROLL,482,485。

矩形区更新消息:WM_DESTROY

窗口客户区消息:WM_PAINT

鼠标消息:WM_NCMOUSEMOVE,WM_MOUSEMOVE

2 . WMHooksThread 中用SimpleUpdateTracker new_changes记录新的更新区域

WMHooksThread::run() 函数中先判断出矩形区域改变的大小,然后调用NotifyHooksRegion(const Region& r)把改变的区域记录到SimpleUpdateTracker new_changes中。

NotifyHooksRegion(const Region& r) {

Lock l(hook_mgr_lock);

std::list<WMHooks*>::iterator i;

for (i=hooks.begin(); i!=hooks.end(); i++) {

(*i)->new_changes.add_changed(r);

if (!(*i)->notified) {

(*i)->notified = true;

PostMessage((*i)->getHandle(), WM_USER, 0, 0); // 把消息通知到clipper见下面一个处理函数

}

}

}

3.把更新区域拷贝到SDisplay中

rfb::win32::WMHooks::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {

switch (msg) {

case WM_USER:

{

Sleep(0);

Lock l(hook_mgr_lock);

notified = false;

new_changes.get_update(*clipper); //把更新通知到clipper中

new_changes.clear();

}

break;

}

return MsgWindow::processMessage(msg, wParam, lParam);

}

Cliper在下面设置

rfb::win32::WMHooks::setUpdateTracker(UpdateTracker* ut) {

if (clipper) delete clipper;

clipper = new ClippedUpdateTracker(*ut);

clipper->set_clip_region(clip_region);

return AddHook(this);

}

UpdateTracker* ut 为void SDisplay::start(VNCServer*vs)中设置core->wm_hooks.setUpdateTracker(this);

4.把SDisplay中记录的数据传给VNCServerST 对象 core->using_hooks =

在 SDisplay::processEvent(HANDLE event) {

try_update = flushChangeTracker() || try_update; //把变化的区域拷贝到VNCServerST中

if (try_update)

server->tryUpdate(); //把更新发送给服务器

}

flushChangeTracker()实现如下:

bool SDisplay::flushChangeTracker() {

if (change_tracker.is_empty())

return false;

change_tracker.translate(screenRect.tl.negate());

change_tracker.get_update(*server); //server 实际指向VNCServerST 对象该函数把SDisplay中的更新拷贝到VNCServerST中。

change_tracker.clear();

return true;

}

两种数据更新方式:Push机制和Pull机制

Push:

SdisplayCore 中IntervalTimer cursorTimer定时器,每隔10ms尝试着检查一下是否有更新,如果有更新就发送更新给客户端。

第一步:

LRESULT SDisplayCore::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {

case TIMER_CURSOR:

display->triggerUpdate(); //SDisplay* display;

}

第二步:

void SDisplay::triggerUpdate() {

if (core)

SetEvent(updateEvent); //使事件对象为受信状态

}

第三步:

SDisplay::processEvent(HANDLE event) {

if (event == updateEvent) {

if (try_update)

server->tryUpdate(); // VNCServer* server指针 指向子类VNCServerST

}

}

第四步:向每一个连接的客户端发送更新

void VNCServerST::tryUpdate()

{

std::list<VNCSConnectionST*>::iterator ci, ci_next;

for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {

ci_next = ci; ci_next++;

(*ci)->writeFramebufferUpdateOrClose();

}

}

第五步:

void VNCSConnectionST::writeFramebufferUpdateOrClose()

{

try {

writeFramebufferUpdate();

} catch(rdr::Exception &e) {

close(e.str());

}

}

第六步:SimpleUpdateTracker updates对象记录更新的区域,如果屏幕有更新则发送更新

void VNCSConnectionST::writeFramebufferUpdate(){

if (!update.is_empty() || writer()->needFakeUpdate() || drawRenderedCursor) {

int nRects = update.numRects() + (drawRenderedCursor ? 1 : 0);

writer()->writeFramebufferUpdateStart(nRects);

Region updatedRegion;

writer()->writeRects(update, &image_getter, &updatedRegion); // SmsgWriter *

updates.subtract(updatedRegion);

if (drawRenderedCursor)

writeRenderedCursorRect();

writer()->writeFramebufferUpdateEnd();

requested.clear();

}

}

第七步:利用RFB协议发送更新

void SMsgWriterV3::writeFramebufferUpdateStart(int nRects)

{

startMsg(msgTypeFramebufferUpdate);

os->pad(1);

if (wsccb) nRects++;

if (needSetDesktopSize) nRects++;

os->writeU16(nRects);

nRectsInUpdate = 0;

nRectsInHeader = nRects;

if (wsccb) {

wsccb->writeSetCursorCallback();

wsccb = 0;

}

}

Poll机制:客户端通过发送更新请求,请求更新某一个区域。

第一步:读取到一个更新某一个区域的请求

void SMsgReaderV3::readMsg()

{

case msgTypeFramebufferUpdateRequest: readFramebufferUpdateRequest(); break;

}

第二步:调用网络事件处理对象handler处理事件

void SMsgReader::readFramebufferUpdateRequest()

{

bool inc = is->readU8();

int x = is->readU16();

int y = is->readU16();

int w = is->readU16();

int h = is->readU16();

endMsg();

handler->framebufferUpdateRequest(Rect(x, y, x+w, y+h), inc);//handler 为 SMsgHandler* handler指针 是指向VNCSConnectionST对象

}

第三步:

void VNCSConnectionST::framebufferUpdateRequest(const Rect& r,bool incremental)

{

if (!(accessRights & AccessView)) return;

SConnection::framebufferUpdateRequest(r, incremental);

Region reqRgn(r);

requested.assign_union(reqRgn);

if (!incremental) {

updates.add_changed(reqRgn);

server->comparer->add_changed(reqRgn);

}

writeFramebufferUpdate();

}

第四步:SimpleUpdateTracker updates对象记录更新的区域,如果屏幕有更新则发送更新

void VNCSConnectionST::writeFramebufferUpdate(){

if (!update.is_empty() || writer()->needFakeUpdate() || drawRenderedCursor) {

int nRects = update.numRects() + (drawRenderedCursor ? 1 : 0);

writer()->writeFramebufferUpdateStart(nRects);

Region updatedRegion;

writer()->writeRects(update, &image_getter, &updatedRegion); // SmsgWriter *

updates.subtract(updatedRegion);

if (drawRenderedCursor)

writeRenderedCursorRect();

writer()->writeFramebufferUpdateEnd();

requested.clear();

}

}

第五步:利用RFB协议发送更新

void SMsgWriterV3::writeFramebufferUpdateStart(int nRects)

{

startMsg(msgTypeFramebufferUpdate);

os->pad(1);

if (wsccb) nRects++;

if (needSetDesktopSize) nRects++;

os->writeU16(nRects);

nRectsInUpdate = 0;

nRectsInHeader = nRects;

if (wsccb) {

wsccb->writeSetCursorCallback();

wsccb = 0;

}

}

更多相关推荐:
项目情况说明范本

各市财政奖励项目资金清算申请材料编写要求规范格式1实施单位及项目名称按照国家下达文件不能有错2项目基本情况要说明包括项目总投资万元技术改造主要内容应与国家下达实施方案严格一致工程建设开始时间主要完成内容竣工时间...

各种证明范本

范文一个人收入证明个人收入证明兹有我公司员工性别身份证号码在我司工作年任职部门职位月收入为人民币元特此证明公司加盖公章年月日个人收入证明兹证明是我公司员工性别身份证号码在部门任职务月收入元一年总收入约为元特此证...

单位工作证明范本

单位工作证明范本工作证明兹有我单位同志身份证号在部门从事工作已有年特此证明单位名称日期加盖单位公章工作证明XXX于200x年x月x月在我单位工作特此证明XXX电脑城二x年x月x日证明xx于xx年xx月xx日到我...

公司名称变更说明范本2

公司名称变更说明城建八建公司本公司因业务发展需要经国家工商行政管理局审核公司名称由原濮阳市华旗建设工程有限公司变更为河南华旗建设工程有限公司特此说明单位落款年月日

装修情况说明范本

装修情况说明推荐文本北京市住房和城乡建设委员会我单位建设单位名称申请项目名称的装饰装修工程施工许可现就项目装修情况说明如下一装修范围本次装饰装修工程范围为房屋产权证产权证号中的栋号产权登记建筑面积平方米实际装修...

情况说明范本

情况说明本人XX身份证号曾于XX年XX月至XX年XX月在XX公司工作签订劳动合同并交纳社保因个人原因导致劳动关系档案丢失一切后果由本人承担与现单位无关特此声明姓名日期

材 料 说 明 范本

材料说明单合同编号地址1水管联塑牌PPR管管径为46分排水为PVC联塑牌2电线佛山禅城牌广州新兴牌多芯铜芯线联塑牌PVC管管径为4分照明线15M2插座线为25M2空调线为4M23弱电安普牌网络线电话线电视线按国...

岗位职责说明书范本

职位工作说明书职位工作说明书

消防工程施工方案范本

施工组织设计方案建设单位:监理单位:消防工程有限公司年月日消防工程施工方案一、工程概况消防工程,楼共层(地下层.地上层).楼消防系统包括.自动报警系统、喷淋系统、消火栓系统、应急照明系统、上述系统分别分布在楼的…

路面施工方案范本1

石灰稳定土基层路拌法施工1材料要求土灰除满足规范要求外施工中控制点为1石灰应符合级以上标准石灰在使用前10天充分消解并过筛10MM筛孔2消石灰存放时间宜控制在2个月以内3以便对压实度进行准确控制2准备下承层1沉...

道路及管网施工方案范本

西吉县廉租房钰秀家园附属工程施工组织设计目录第一章第二章第三章第四章第五章第六章第七章第八章第九章附123456工程概况分部分项工程主要施工方法拟投入工程的主要施工机械设备情况劳动力安排计划确保工程质量的技术组...

施工方案范本

土木工程施工技术课程设计第一章概况第一节工程概况1工程名称银川市茶叶公司扩建工程主体第九层2建设面积101268平方米3楼层层数地下一层地上九层4单位层高九层层高36m5结构形式钢筋砼框剪结构6基础类型混凝土片...

说明范本(29篇)