基于Linux的远程控制技术服务端实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

计算机毕业设计论文网
学位论文
基于Linux的远程控制技术服务端实现
论文作者姓名:
申请学位专业:
申请学位类别:
指导教师姓名(职称):)
论文提交日期:
基于Linux的远程控制技术服务端实现
摘要
现阶段基于windows平台下的远程控制软件相当多,各种开发语言参差不齐。

本课题基于C/S架构,实现了Linux平台下的远程控制,整个系统运用成熟的Perl和C语言,根据软件设计模式思想,实现了x-windows远程桌面支持、远程命令行模式以及安全连接支持,比纯粹的命令行环境更方便工作和学习,具有一定的科学性、安全性、创新性。

这对于深入了解Linux下的远程控制技术以及远程控制的运作方式,进一步提高自身网络的可控性有着重要的实际意义,并且为进一步开展这方面的研究提供了良好的研究平台。

关键词:远程控制;网络;Linux
Implementation on the server of Remote Control
Technology based on Linux
Abstract
Nowadays the overflow of Remote control software which is based on windows platform is obvious and the development of various languages is also uneven. this system realized Remote control based on Linux platform by using mature Perl and C language, and it has achieved the remote table top support of X-windows and the remote command line pattern supply along with the secure joint support that makes it more convenient to work and study than on pure command line environment So this system is more scientific, more safe and more innovational.
This system has important practical significance, it helps to comprehend the Linux remote control technique in-depth and to understand the operation of remote control, and this system has further enhanced the controllability of their own network, and offered a good platform for further research in the field.
Key words:Remote control; Network; Linux
目录
论文总页数:23页1 引言 (1)
1.1远程控制技术简述 (1)
1.2 远程控制技术的作用 (2)
1.3 远程控制技术的应用现状及发展趋势 (2)
2 远程控制系统的背景与需求分析 (2)
2.1 Linux平台下远程控制系统的产生 (2)
2.2 Linux平台下远程控制系统的需求分析 (3)
3 远程控制系统的总体设计 (4)
3.1 编程基础的介绍 (4)
3.2远程控制系统tightvnc服务端的设计 (8)
4 远程控制系统tightvnc服务端的实现 (10)
4.1 远程控制系统tightvnc服务端源代码分析 (10)
4.1.1服务端主程序代码及分析 (10)
4.1.2服务端相关功能代码及分析 (13)
4.1.3服务端密码相关代码及分析 (15)
4.2 远程控制系统tightvnc的相关功能 (17)
5 远程控制系统tightvnc的测试 (18)
5.1 远程控制系统tightvnc服务端使用说明 (18)
5.2 远程控制系统tightvnc的总体评价 (20)
5.3远程控制系统tightvnc尚未解决的问题 (21)
结论 (21)
参考文献 (21)
致谢 (22)
声明......................................................................................................... 错误!未定义书签。

1 引言
你是不是有过这样的经历呢?你在办公室里上班,但是很遗憾你忘了一些重要的文件在家里的计算机机上,这时你该如何应付呢?这可能是很头疼的事情吧。

随着计算机网络的出现,这一问题就迎刃而解了。

这便是今天大家所熟悉的远程控制。

有了远程控制技术,你就不必跑回家拷贝文件了,只要通过办公室拨号上网或者通过VNP方式就能访问你家里的计算机,输入用户名和密码,就能轻松拷贝到你需要的文件。

因此,不管在工作或学习中都有很强的实用性,可以使人们的生活变得更加轻松简单。

然而大多数的远程控制都是在微软Windows操作系统下。

那么在Linux平台中是否也能实现远程控制呢?
本论文就讨论了Linux下基于web的远程控制技术的原理和开发过程。

远程控制软件基本上是由两部分组成:一部分是客户端的应用程序;另一部分是服务端的应用程序。

远程控制软件的服务端应用程序在UNIX和Linux操作系统中适应性很强,图形用户界面友好。

操作过程和显示方式比较直观方便。

1.1远程控制技术简述
远程控制是指通过计算机网络,对分布在网络上的计算机实现远程控制、协同工作。

这种控制是通过对基于网络通讯的标准通讯协议和对目标机的操作系统响应方式的准确控制来实现的。

远程控制技术是一个涉及到操作系统原理、网络技术、通信技术、网络安全技术等多种科学领域的新的计算机应用与研究方向。

远程控制软件是基于一定的物理网络(如internet网、企业、校园的局域网等),通过一定的网络协议(如TCP/IP协议),实现对远程计算机的远行方式的控制。

通过远程控制软件,可以实现在远程计算机上按控制软件的要求来运行程序、终止程序、同步时间、注销用户、修改设置等各种操作。

也可以在本地实现自动跟踪远端计算机的屏幕变化、记录各种口令信息、获取系统信息、限制系统功能、任意操作文件及注册表、远程关机、发送信息等多种监控功能。

就如同用户亲自坐在被控制端操作一样,可以执行被控制端的应用程序,及使用被控制端的系统资源。

随着计算机网络的飞速发展,全球信息化已经成为人类发展的趋势。

远程控制也将对人们提高工作效率,实现信息和资源共享。

所以,对于远程控制技术的研究具有很深远的意义。

1.2 远程控制技术的作用
1. 远程办公
通过远程控制功能我们可以轻松的实现远程办公,这种远程的办公方式新颖,轻松,从某方面来说可以提高员工的工作效率和工作兴趣。

2.远程技术支持
远距离的技术支持必须依赖技术人员和用户之间的电话交流来进行,这种交流即耗时又容易出错。

但是有了远程控制技术,技术人员就可以远程控制用户电脑,就像直接操作本地电脑一样,只需要用户的简单帮助就可以得到该计算机存在的问题的第一手资料,很快就可以找到问题的所在,并加以解决。

3.远程交流
利用远程技术,商业公司可以实现和用户的远程交流,采用交互式的教学模式,通过实际操作来培训用户,使用户从技术支持专业人员那里学习示例知识变得非常容易。

而教师和学生之间也以利用这种远程控制技术实现教学问题的交流,学生可以不用见到老师,就得到老师手把手的辅导和讲授。

学生还可以直接在电脑中进行习题的演算和求解,在此过程中,教师能够轻松看到学生的解题思路和步骤,并加以实时的指导。

4.远程维护和管理
网络管理员或者普通用户可以通过远程控制技术为远端的电脑安装和配置软件、下载并安装软件修补程序、配置应用程序和进行系统软件设置。

1.3 远程控制技术的应用现状及发展趋势
远程控制就目前状况来说,在微软Windows操作系统中的远程控制工具软件非常多,其中大家最熟悉的有塞门铁克公司的PC ANYWHERE,还有CA ControlIT 等等。

这些远程控制工具软件都可以通过网络来控制特定的计算机,共享那台计算机的数据资料,操作其外部设备。

而在Linux操作系统中也是存在几款功能强大的远程控制工具软件,只是这些软件非常少,使用的用户也不是很多。

随着网络技术和通信技术的发展,远程控制技术也将得到迅速的发展和广泛的应用,那么Linux平台中的远程控制技术的发展前景更是备受关注的。

2 远程控制系统的背景与需求分析
2.1 Linux平台下远程控制系统的产生
远程控制系统在现代社会有着越来越广泛的应用。

远程控制中的嵌入技术、
远程控制的数据处理与传输、远程控制的管理和远程控制的终端都取得了广泛的发展。

远程控制系统一般模型的构建及其实现的研究对今后开发远程控制系统有着良好的指导意义。

在互联网领域Linux系统使用得相当广泛,现阶段基于windows的远程控制系统相当齐全,而基于Linux的远程控制系统相对很少,结合实际工作中对Linux的本地需求与运用,产生了通过网络的远程应用。

Linux操作系统的运用越来越广泛,是真正的多用户、多任务操作系统,他继承了UNIX系统的主要特征,具有强大的信息处理能力,特别在Internet和Internet的应用中占有很明显的优势。

与其他操作系统相比,具有一系列显著的特点:
1.与UNIX兼容
现在,Linux已经成为具有全部UNIX特征,所有UNIX的主要功能都有相应的Linux工具和实用程序。

2.自由软件和源码公开
任何人都可以自由使用Linux源程序,这样就激发了世界范围内热忠于计算机事业的人们的创造力。

通过Internet,这一软件得到迅速传播和广泛使用。

3.性能高和安全性强
Linux上包含了大量网络管理、网络服务等方面的工具,用户可利用它来建立高效稳定的防火墙、路由器等。

由于源码公开,所以可消除系统中是否有“后门”的疑惑。

Linux是公认的安全的操作系统,因为它的内核是可见的,它的源代码是公开的可以由任何对它进行操作的人进行修改。

所以许多企业的网络服务器都首选LINUX操作系统。

远程控制系统的首要目的就是要远程接入一个安装有Linux操作系统的机器中,如何在远程计算机的安全机制允许下合法或者非法接入远程计算机是远程控制系统的基本问题。

2.2 Linux平台下远程控制系统的需求分析
经过分析,远程控制软件需要提供一个基于C/S(即客户端/服务器端)模式用户接口,它允许一个用户来管理本地电脑上的桌面项目或者说应用功能的实现,用户能够通过自己的电脑控制远端的计算机,并能够利用自己的鼠标和键盘直接对远端的桌面进行控制,实现远程桌面的控制、屏幕控制、对文件的查看和修改等功能。

基于Linux下的远程控制的产生符合以下几点的需要:
1、现阶段Linux广泛地应用于日常生活与工作,Linux下的应用软件需要更进一步的发展。

2、基于SSH协议的远程管理对一般用户来说易用性低,易用性需要提高。

3、基于Linux课题的创新。

通过分析GNU公共软件VNC的设计原理和开发过程,结合实际的需求开发了这个系统,并命名为tightVNC。

3 远程控制系统的总体设计
3.1 编程基础的介绍
Unix是计算机使用的主流操作系统之一,TCP/IP是广为应用的互联网协议,Unix为TCP/IP网络编程提供了一种网络进程通信机制:套接字接口(Sockets Interface)。

以下将介绍Unix环境下套接字的基本概念及编程技术,并结合实例说明在Unix下如何用套接字实现客户机/服务器方式的进程通信。

1、套接字简介
套接字(Socket)是网络通信的基本操作单元,它提供了不同主机间进程双向通信的端点,这些进程在通信前各自建立一个Socket,并通过对Socket的读/写操作实现网络通信功能。

套接字分为以下3种类型。

1) 字节流套接字
这是最常用的套接字类型,TCP/IP协议簇中的TCP(Transport Control Protocol)协议使用此类接口,它提供面向连接的(建立虛电路)、无差错的、发送先后顺序一致的、包长度不限和非重复的网络信包传输。

2) 数据报套接字
TCP/IP协议族中的UDP(User Datagram Protocol)协议使用此类接口,它是无连接的服务,以独立的信包进行网络传输,信包最大长度为32KB,传输不保证顺序性、可靠性和无重复性,它通常用于单个报文传输或可靠性不重要的场合。

3) 原始数据报套接字
提供对网络下层通讯协议(如IP协议)的直接访问,它一般不是提供给普通用户的,主要用于开发新的协议或用于提取协议较隐蔽的功能。

2、套接字编程方法
这里将分别介绍面向连接协议的字节流套接字与非连接协议的数据报套接字的编程方法,因原始数据报套接字在实际工作中较少,在此不作讨论。

不论何种套接字编程均采用客户机/服务器的协作模式,即由客户进程向服务器进程发出请求,服务器进程执行被请求的任务并将结果返回给客户进程。

字节流套接字的服务进程和客户进程在通信前必须建立连接。

建立连接及通信的步骤见图1。

1) 服务进程首先调用Socket()创建一个字节流套接字,并调用bind()将服
务器地址捆扎在该套接字上,接着调用listen()监听连接请求 ,随后调用accept()做好与客户进程建立连接的准备,无连接请求时,服务进程被阻塞;
2) 客户进程调用Socket()创建字节流套接字,然后调用connect()向服务进程发出连接请求;
3) 当连接请求到来后,服务进程被唤醒,生成一个新的字节流套接字,并用新套接字同客户进程的套接字建立连接,而服务进程最早生成的套接字则继续用于监听网络上的服务请求;
4) 服务进程和客户进程通过调用read()和write()交换数据;
5) 服务进程和客户进程通过调用close()撤消套接字并中断连接。

数据套接字的服务进程客户进程通信前不必建立连接, 通信的步骤见图2。

1) 服务进程首先调用Socket()创建一个数据套接字,并调用Bind()将服务
阻塞直到接收到客户
连接请求协调连接数据(请求)结束连接图1 面向连接协议的字节流套接字调用
器地址捆扎在该套接字上,然后调用Recvfrom()等待客户进程发来的请求;
2) 客户进程在调用Socket()创建一个数据报套接字后,调用Bind()将客户机地址捆扎在此套接字上,接着调用Sendto()向服务进程发送请求,然后调用Recvfrom()等待服务进程返回该请求的处理结果;
3) 服务进程在执行客户进程所请求的任务后,调用Sendto()将处理结果返回给客户进程;
4) 服务进程和客户进程通过调用Close()撤消套接字。

3、套接字编程示例
下面给出一个运用字节流套接字在TCP/IP 网络上实现客户机/服务器方式进程通信的实例。

在此例中,服务进程先于客户进程运行,当双方建立连接后,服务进程通过该连接向客户进程不断发送一个连续增长的序列数,客户进程每接收到50个序列数就在屏幕上显示一个‘.’,显示至20个点后换行,直至任意一方进程被中断为止。

数据(请求)
数据(响应)图2 非连接协议的报套接字调用
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netdb.h>
# include <stdio.h>
main()
{
int sock,namelen,seq,netint;
struct sockaddr-in server;
//存服务器的internet地址
char msgsock;
char buf[1024];
//创建internet域的TCP协议的字节流套接字
sock=socket(AF-INET,SOCK-STREAM,IPPROTO-TCP);
if(sock<0) {
perror("socket");
exit(1);
}
//将本地主机(服务器)的地址捆扎到创建的套接字上server.sinfamily=AF-INET;
//internet域
sevrer.sinaddr.s-addr=INADDR-ANY; //使用任意合法地址sevrer.sinport=htons(1032);
//公认的服务端口号
if(bind(sock,&server,sizeof(server))<0){
perror("bind");
exit(2);
}
//阻塞至客户方有连接请求到来,建立一新套接字用于通信namelen=sizeof(server);
if((msgsock=accept(sock,&server,&namelen))<0){ perror("accept");
exit(4);
}
//此时连接已建立,可以进行通信
seq=0;
for(;;){
netint=htonl(seq);
//主机字节顺序转为网络字节顺序
write(msgsock,&netint,4);
//向客户方写序列数
seq++;
}
}
3.2远程控制系统tightvnc服务端的设计
TightVNC的整体结构如图3所示:
图3 总体设计模板
其服务端的主要功能模块结构如下:
其核心框架就是四个类vncClient,vncServer,vncDesktop和vncBuffer.下面我就这四个类之间的联系和用途作一下简单的分析:
vncServer:
vncServer主要是做如下的一些工作:容许vncClient动态的添加和删除;
将本地vncDesktop对象内部状态的任何改变“传播”到各个客户端;传播客户端的鼠标和键盘事件到本地的vncDesktop对象。

同时,其还创建了vncSockConnect,vncCORBAConnect和vncHTTPConnect来接受Socket,Corba 和HTTP的连接。

vncServer为每个连接上来的客户端分配了一个ClientID(其实就是内部客户对象数组的Index),并且提供了对客户端管理的众多函数库。

同时,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中各个客户的同样的方法的函数调用。

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):
首先调用vncDestktop::Startup初始化,vncDesktop对象,然后就是处理桌面消息,调用m_server->UpdateMouse()和m_server->UpdateRegion(),接下来调用vncServer::TriggerUpdate来发送屏幕更新到每个vncClient。

然后就是处理RFB_SCREEN_UPDATE和RFB_MOUSE_UPDATE这两个注册消息。

vncClient:
vncClient做了数据发送的工作,在vncClient::SendUpdate函数的实现中,我们可以看到vncClient调用SendRFBMsg首先发送,然后SendCursorShapeU发送鼠标形状更新,SendCursorPosUpdate发送鼠标Pos更新,发送SendCopyRect,最后调用SendRectangles发送需要更新的矩形的相关数据。

其实每个客户端vncClient在调用vncClient::Init初始化的时候都开了一个线程,客户端的行为基本上都是在vncClientThread::run里完成的。

该线程在跟客户端交互完成了认证,Pixel格式,Encoding算法等信息的协商后,就进入loop循环开始接受和处理远程客户端发过来的rfbKeyEvent,rfbFramebufferUpdateRequest,rfbPointerEvent,rfbSetEncodings,rfbSetPixelFormat, rfbClientCutText 消息。

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

4 远程控制系统tightvnc服务端的实现
4.1 远程控制系统tightvnc服务端源代码分析
4.1.1服务端主程序代码及分析
#全局变量定义和配置:
$geometry = "1024x768";
$depth = 16;
$vncJavaFiles = (((-d "/usr/share/vnc/classes") && "/usr/share/vnc/classes") ||((-d "/usr/local/vnc/classes") && "/usr/local/vnc/classes"));
$vncUserDir = "$ENV{HOME}/.vnc";
$xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority";
$defaultXStartupi
= ("#!/bin/shi\n\n".
"# Uncomment the following two lines for normal desktop:\n".
"# unset SESSION_MANAGER\n".
"# exec /etc/X11/xinit/xinitrc\n\n".
"[ -x /etc/vnc/xstartupi ] && exec /etc/vnc/xstartup\n".
"[ -r \$HOME/.Xresources ] && xrdb \$HOME/.Xresources\n".
"xsetroot -solid grey\n".
"vnccionfig -iconic &\n".
"xterm -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n".
"twm &\n");
chop($host = `uname -n`);
# 检查命令行选项
&ParseOptions("-geometry",1,"-depth",1,"-pixelformat",1,"-name",1,"-kill",1, "-help",0,"-h",0,"--help",0);
&Usage() if ($opt{'-help'} || $opt{'-h'} || $opt{'--help'});
&Kill() if ($opt{'-kill'});
# 匹配x终端
# &GetXDisplayDefaults();
if ($opt{'-geometry'}) {
$geometry = $opt{'-geometry'};
}
if ($opt{'-depth'}) {
$depth = $opt{'-depth'};
$pixelformat = "";
}
if ($opt{'-pixelformat'}) {
$pixelformat = $opt{'-pixelformat'};
}
&CheckGeometryAndDepth();
# 创建用户目录
if (!(-e $vncUserDir)) {
if (!mkdir($vncUserDir,0755)) {
die "$prog: Could not create $vncUserDir.\n";
}
}
# 验证密码非空.
($z,$z,$mode) = stat("$vncUserDir/passwd");
if (!(-e "$vncUserDir/passwd") || ($mode & 077)) {
warn "\nYou will require a password to access your desktops.\n\n";
system("vncpasswd -q $vncUserDir/passwd");
if (($? >> 8) != 0) {
exit 1;
}
}
#启动服务:
$cmd = "Xvnc :$displayNumber";
$cmd .= " -desktop " . &quotedString($desktopName);
$cmd .= " -httpd $vncJavaFiles" if ($vncJavaFiles);
$cmd .= " -auth $xauthorityFile";
$cmd .= " -geometry $geometry" if ($geometry);
$cmd .= " -depth $depth" if ($depth);
$cmd .= " -pixelformat $pixelformat" if ($pixelformat);
$cmd .= " -rfbwait 30000";
$cmd .= " -rfbauth $vncUserDir/passwd";
$cmd .= " -rfbport $vncPort";
$cmd .= " -pn";
# 添加字体与颜色库
# $cmd .= " -fp /usr/lib/X11/fonts/misc/,/usr/lib/X11/fonts/75dpi/";
# $cmd .= " -co /usr/lib/X11/rgb";
#
foreach $arg (@ARGV) {
$cmd .= " " . &quotedString($arg);
}
$cmd .= " >> " . &quotedString($desktopLog) . " 2>&1";
#运行shell及记录进程号.
$pidFile = "$vncUserDir/$host:$displayNumber.pid";
system("$cmd & echo \$! >$pidFile");
# 配置服务自启动
sleep(3);
warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n";
# Create the user's xstartup script if necessary.
if (!(-e "$vncUserDir/xstartup")) {
warn "Creating default startup script $vncUserDir/xstartup\n";
open(XSTARTUP, ">$vncUserDir/xstartup");
print XSTARTUP $defaultXStartup;
close(XSTARTUP);
chmod 0755, "$vncUserDir/xstartup";
}
#X-windows启动脚本:
warn "Starting applications specified in $vncUserDir/xstartup\n";
warn "Log file is $desktopLog\n\n";
# If the unix domain socket exists then use that (DISPLAY=:n) otherwise use # TCP (DISPLAY=host:n)
if (-e "/tmp/.X11-unix/X$displayNumber" ||
-e "/usr/spool/sockets/X11/$displayNumber")
{
$ENV{DISPLAY}= ":$displayNumber";
} else {
$ENV{DISPLAY}= "$host:$displayNumber";
}
$ENV{VNCDESKTOP}= $desktopName;
system("$vncUserDir/xstartup >> " . &quotedString($desktopLog) . " 2>&1 &"); exit;
4.1.2服务端相关功能代码及分析
1、IActiveDesktop
允许一个客户端管理通过封装管理远程桌面。

#include
IActiveDesktop* active_desktop = 0;
CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_IActiveDesktop, (void**)&active_desktop);
// 设置进程最后被关闭
SetProcessShutdownParameters(0x100, 0);
2、One Instance Running by Mutex
使用 Mutex 对象确认当前操作系统中仅一个进程被启动。

const char mutexname [] = "WinVNC_Win32_Instance_Mutex";
BOOL vncInstHandler::Init()
{
// 创建 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;
sscanf
Read formatted data from a string.
// 检查协议版本
int major, minor;
sscanf((char *)&protocol_ver, "RFB %03d.%03d\n", &major, &minor);
3、关闭屏幕进程
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);
// 屏幕关闭等候
//设置关闭延时
// 屏幕重启
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,TRUE,0,SPIF_SENDWININICHANG
E);
}
break;
}
Disable Nagle Algorithm
BOOL nodelayval = TRUE;
setsockopt(m_sock,IPPROTO_TCP,TCP_NODELAY,(constchar*)&nodelayval,
sizeof(BOOL));
4、Poll Schemai
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
4.1.3服务端密码相关代码及分析
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include "vncauth.h"
//输入输出等相关函数调用
Static void usage (char *argv[]);
Static char *getenv_safe(char *name, size_t maxlen);
Static void mkdir_and_check(char *dirname, int be_strict);
Static int read_password(char *result);
Static int ask_passwordi(char *result);
//主函数
int main(int argc, char *argv[])
{
int read_from_stdin = 0;
int make_directory = 0;
int check_strictly = 0;
Char passwd1 [9];
Char passwd2 [9];
Char *passwd2_ptr;
Char yesno[2];
Char passwdDir[256];
Char passwdFile[256];
int i;
//判断参数是否为空
if (argc == 1) {
sprintf(passwdDir, "%s/.vnc", getenv_safe("HOME", 240));
sprintf(passwdFile, "%s/passwd", passwdDir);
read_from_stdin = 0;
make_directory = 1;
check_strictly = 0;
} else if (argc == 2) {
// 检查加密协议
If (strcmp(argv[1], "-t") == 0) {
sprintf(passwdDir, "/tmp/%s-vnc", getenv_safe("USER", 32)); sprintf(passwdFile, "%s/passwd", passwdDir);
read_from_stdin = 0;
make_directory = 1;
check_strictly = 1;
} else if (strcmp(argv[1], "-f") == 0) {
strcpy(passwdFile, "-");
read_from_stdin = 1;
make_directory = 0;
check_strictly = 0;
} else {
If (strlen(argv[1]) > 255) {
fprintf(stderr, "Error: file name too long\n");
Exit (1);
}
strcpy(passwdFile, argv[1]);
read_from_stdin = 0;
make_directory = 0;
check_strictly = 0;
}
} else {
Usage (argv);
}
//目录结构生成
if (make_directory) {
fprintf(stderr, "Using password file %s\n", passwdFile);
mkdir_and_check(passwdDir, check_strictly);
}
passwd2_ptr = NULL;
if (read_from_stdin) {
//输入流读取密码
if (!read_password(passwd1)) {
fprintf(stderr, "Could not read password\n");
Exit (1);
}
If (read_password(passwd2)) {
passwd2_ptr = passwd2;
}
}
4.2 远程控制系统tightvnc的相关功能
功能列表:
1、系统命令行
1) 动态桌面
允许一个客户端管理通过封装管理远程桌面。

2) 设置进程参数
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.
3) 运行矢量检查
使用 Mutex 对象确认当前操作系统中仅一个进程被启动。

4)屏幕扫描
Read formatted data from a string.
5) 关闭屏幕保护
6) Diable Nagle Algorithm
Nagle Algorithm主要是用于优化小数据包的发送,用于在IP栈中缓冲小数据包,积累一定数量的小数据包一起发送。

这样可以减少系统发包的数量,Nagle Algorithm实现时内部也有一个Timeout机制,但这个Timeout时间长度不能在外部设置。

而且对每个IP栈的实现,这个Timeout Span 都有一个实现相关的值。

2、Screen Capture
Poll Schema
Poll方式就是最简单的一种方式了,也是在考虑截屏时最先想到一个解决方案。

为取得系统的屏幕,poll方案每33ms轮询一次系统屏幕,将变化的部分添加加到一个UpdateRegion中。

为获取这些屏幕变化的Rect,系统还采取了一种优化Polling算法,将屏幕分为32*32 pixel的小矩形块。

5 远程控制系统tightvnc的测试
5.1 远程控制系统tightvnc服务端使用说明
1、JPEG and zlib libraries makefile文件的生成
% xmkmf
% make World
2、服务端配置与编译
% cd Xvnc
% ./configure
% make
3、设置环境PATH
% cd ..
% ./vncinstall /usr/local/bin /usr/local/man
4、启动服务端初始配置连接密码如图4所示
5、客户端连接测试如图5所示
6、输入密码连接成功如图6所示
远程x-windows 桌面如图7所示
图6密码连接
图5客户端连接
图4初始配置。

相关文档
最新文档