远程桌面控制VC源码剖析
2012-08-08 11:21
274 查看
一、引语
这是个VC6.0的远程桌面控制软件,主要功能是桌面控制、支持多种压缩方式、可调整网格空间数目以及色彩模式选择。源码我也不知道从何而来了,今天整理硬盘无疑间发现的。软件中作者没有留名,很老的一个软件,各种办法也没找到出处,那么就当这个软件是一个开源软件吧。二、结构分析
拿到代码,先看服务器端,RemoteControlServer 文件。目录结构:(cmd> tree /f |more生成,略有修改)
E:.RemoteControlServer
│ afiedt.buf
│ .........................
│ ServerWindow.001
│ ServerWindow.dsp
│ ServerWindow.dsw
│ ServerWindow.mak
│ ServerWindow.ncb
│ ServerWindow.opt
│ ServerWindow.plg
│ ........................
└─WndProc.h
目录中有*.dsp、*.dsw文件 ,明显可以看出是vc项目。那么有可能是MFC或者win32/win32 console。
用VS2008打开RemoteControlServer项目,查看类视图,class CMainWnd;只有这一个用户的非继承类,看来不可能是MFC了,倒是很像Win32。
接下来就要先找到WinMain或者main函数了,因为文件没几个,凭着直觉和命名规范,果断在WndProc.cpp找到了WinMain。
因为Win32窗口使用的是消息循环机制,那么直接从WinMain开始看代码了。在WinMain中将回调WndProc函数,OnCreate、OnDestroy、OnKeyDown、OnCommand回根据窗口的消息调用,这样就不难理解程序的结构。
整体的结构可以看图,只是为了整体结构的体现,很多地方进行了省略。图一如既往的烂(第二次使用visio我会说么?)
三、网络编程部分
MainWnd.cpp (63L) CMainWnd::OnCreate 中,进行Winsock初始化。CMainWnd::OnCommand (160L)中,创建LoadWinsock线程进行通信。
Server.c (72L) SelectProtocols函数把一些协议相关的信息放入了pBuf缓冲中,但是pBuf是怎么和套接字关联起来的呢?从头到尾没用过。而且我把SelectProtocols函数调用的那一句注释之后编译,一样能成功链接通信。那这里调用SelectProtocols是怎么起到作用的呢?
Server.c (991L) SelectProtocols函数主要主用是:
1、让所有报文都能到达目的
2、让所有报文都有序到达
3、不使用数据报套接字通信
SelectProtocols函数中有调用memblast,memblast是用内嵌汇编实现的内存拷贝函数,可能是为了某些平台移植、或者程序编译时不使用平台提供的基本运行时。(感谢BinSys解疑)
为了减小CPU的利用率,禁止在socket上将数据发送到缓冲。设置SO_SNDBUF为0,从而使winsock直接发送数据到客户端,而不是将数据缓冲才发送。(msdn:setsockopt)
nZero = 0; setsockopt(Listen, SOL_SOCKET, SO_SNDBUF, (char *)&nZero, sizeof(nZero));
Server.c (105L) 等待用户连接是一个循环等待并阻塞的过程,并且一直等待用户来连接。
一旦有用户连接到服务器,就会进入新的线程ClientThread;
在ClientThread又用了select模型,只有一个用户,也没有设置超时时间,并且select也不比普通的直接recv阻塞等待快啊。这个真的很难理解。难道是为了程序的拓展性(为多用户或者超时之后做一点别的事么?)
从应用层来分析 协议 ,这个程序使用的是各种“命令”。
1.REFRESH
2.WM_系列
3.RESOLUTION
4.DISCONNECT
WM_是一个系列,又分成三个字系列.
1.鼠标消息
2.键盘消息
3.通用消息:
色彩模式,网格数和压缩消息
四、屏幕采集部分
这部分主要是就服务器采集屏幕,然后发送给客户端。定时采集屏幕发送给用户?不,这样流量的不能接受,而且是没必要的。
采用每次屏幕改变的时候才返回新的屏幕呢?看样子不错,但是还可以优化。
把屏幕划通过网格分成很多小块,每次只发送改变的那些块,这样还不错吧?
这个程序就是这样设计的,并且也是这个程序设计最巧妙的地方。如果做到最好就是,直接获得变化的那些区域,发送变化的那个区域过去,这个区域很有可能是不规则的。用网格的办法来说,就是网格的每个区域分辨率只有1*1,但是不可能这样做了,要保留所有变化的像素点,不停的遍历对比每一个像素,这样无疑增加是CPU的负担。获得屏幕变化的部分是通过对比位图的出来的(Server.c (683L))。
MainWnd.cpp (166L) 调用InitDisplay初始化。屏幕刷新是用户提出的请求,当服务器收到刷新屏幕的请求之后,首先获取需要刷新的网格区域,对位图进行压缩获取需要发送的小块,采用压缩发给用户。用户通过解压显示图片。
五、数据压缩
图片之所以需要压缩,是因为捕捉到的屏幕是一块位图(bitmap)。
色彩的表示是由R、G、B组成, bitmap包含图片每一个像素点的信息(R、G、B分别占8个二进制位,那么R、G、B的的范围恰好是0-255),32位的bmp位图还用了1字节来作为alpha通道,每一个像素点占32位。24位位图俗称“真彩”,因为保留了所有的信息,所以体积很大。
色彩还有另一种表示的方法(jpeg),是灰度、亮度、对比度,因为人眼睛的特殊,这种标准的图片有一定失真,但是肉眼难以判断。简单的说,由于压缩的原因,这种图片每一个像素点RGB值是由周围一些像素点一起决定的。
本程序中压缩采用了:
1.单遍
霍夫曼编码(Huffman)压缩
2.多遍霍夫曼压缩编码
3.
Run Length编码(游程编码)
4.Run Length&Huffman编码
之前有看过一点计算机图形学, 也做过bmp图片编辑、bmp图片压缩。(秀知识上限了,囧~~~,确实没有好好学过图形学- -#)
六、结束语
看完服务器端,可以说这个程序涉及的知识面还是很广的。win32、网络编程、c++的oop(很少)、位图压缩、汇编等,把服务器端分析完,基本都能猜到客户端是怎么实现的了。源码下载及界面截图:
http://www.oschina.net/code/snippet_583625_12606
相关文章推荐
- VC下远程控制(桌面)的完整实现
- NN远程桌面SDK之VC++开发源码
- gh0st 远程桌面控制源码分析
- VC++远程控制软件的通信架构与源码分析
- 供应P2P远程桌面控制软件,可二次开发,有调用源码
- 前两天用VC6做的修改远程桌面端口的命令行小程序,源码。
- Win7的远程桌面控制使用方法图文详解
- Struts2 源码剖析 控制部分-----1
- XP系统下,远程桌面控制,(确保两台计算机在同一个局域网内)
- Windows下通过xmanager远程桌面控制RHEL4和RHEL5
- 远程桌面控制
- 简单的远程桌面实现(仅观看、不控制)
- windows远程控制centOS桌面
- 安全系列之三:域环境下远程桌面深度剖析及使用 推荐
- 服务器开启远程桌面控制
- win10通过vnc远程控制ubuntu桌面
- C++Buffer缓冲区-Gh0st远程控制源码摘取
- windows xp下远程桌面控制
- mstsc:远程桌面控制命令