基于Socket通信的远程控制系统设计-毕业论文

时间:2020-06-26 14:40:14 浏览量:

 浙江工业大学之江学院毕业设计(论文)                                                      

  1 绪 论

 1.1 远程控制系统概述

 远程控制是在网络上由一台主控端计算机远距离地控制另一台被控端计算机的技术。远程控制系统一般分客户端程序(Client)和服务器端程序(Server)两部分,通常将客户端程序安装到主控端的计算机上,将服务器端程序安装到被控端的计算机上[1]。使用时客户端程序向被控端计算机中的服务器端程序发出信号,建立一个特殊的远程服务,然后通过这个远程服务,使用各种远程控制功能发送远程控制命令,控制被控端计算机中的各种应用程序运行[2]。

  当操作者使用客户端计算机控制服务器端计算机时,就如同坐在服务器端计算机的屏幕前一样,可以启动服务器端计算机的应用程序,可以使用服务器端计算机的文件资料,甚至可以利用服务器端计算机的应用程序,可以使用服务器端计算机的外部打印设备(打印机)和通信设备(调制解调器或者专线等)来进行打印和访问互联网,就像利用遥控器遥控电视的音量、改变频道或者开关电视机一样[3]。主控端计算机只是将键盘和鼠标的指令传送给远程计算机进行操作似乎是在眼前的计算机上进行的,实质是在远程的计算机中实现的,不论打开文件,还是上网浏览、下载等都是存储在远程的被控端计算机中的[4]。

  1.2 国内外研究现状及应用

 计算机远程控制技术始于DOS时代,当时由于技术上没有什么大的变化,网络不发达,市场没有更高的要求,所以没有引起更多关注。但是,随着网络的高度发展,计算机的管理及技术的需要,远程操作及控制技术越来越引起人们的关注。远程控制一般支持下面的这些网络方式:LAN、WAN、拨号方式、互联网方式。此外,有的远程控制软件还支持通过串口、并口、红外端口来对远程机进行控制(不过,这里说的远程计算机,只能是的限定距离范围内的计算机了)。传统的远程控制软件一般使用NETBEUI、NETBIOS、IPX/SPX、TCP/IP等协议来实现远程控制,不过随着网络技术的发展,很多远程控制软件提供通过Web页面以JAVA技术来控制远程计算机,这样可以实现不同操作系统下的远程控制,例如数技通科技术有限公司就推出了全球第一套基于中文JAVA的跨平台远程控制软件——易控[5]。

  在应用方面,国内外在远程控制方面的应用十分广泛,而且进展迅速,大体来看分为几种:一是对计算机网络自身性能的监控。这种应用可以自动跟踪目标计算机的屏幕变化、获取目标计算机登录口令及各种密码类信息、获取目标计算机系统信息、限制目标计算机系统功能、任意操作目标计算机文件及目录、远程关机、发送信息等多种监控功能。对于网络管理员、技术服务员和需要远程办公的人员来说,远程控制提供了一种便捷、高效的手段,如著名的

 pcAnywhere软件、ICE冰河软件等就是这种应用;二是对现场状况的实时监控,多用于酒店、银行或住宅等系统监视方面。这种应用使用摄像机云台,实际上是一种被动的监视系统;三是对作业现场有效数据的采集监视,是种主动监控方式,多用于水文水利、电力、机械生产等方面。目前,基于因特网的远程控制国内外电都有不同程度的研究,相对来说,由于西方国家在信息技术和计算机技术的发展上的优势,他们在研究基于因特网的远程控制方面相对早一些,而且主要集中在机器人领域。例如:美国南加州大学研制的可播种和浇水的远程控制花园Telegarden、英国Bradford大学的远程机器人望远镜系统、澳大利亚Wollogong大学拾取木块的Roboty系统、德国以“Hanoi塔”方法搬运木块的Net.Robot等。1997年,美国国家航空航天局(National Aeronautics and Space Administration,NASA)研制的“火星旅居者”远程控制机器人就已经成功地应用于火星计划;2004年1月,NASA的“勇气号”远程机器人成功登陆火星[7]。国内的**工业大学也在研制基于因特网的Telerobot远程控制机器人。

  1.3 本章小结

 本章首先介绍了远程控制系统的基本概念、组成部分,通过远程控制系统可以实现的诸多功能。对传统的远程控制系统进行了说明。同时,介绍了远程控制系统的发展历史,国内外在远程控制主要三方面的应用。最后通过世界各国的远程控制成功的案例介绍了远程控制系统各个领域的应用,说明了远程控制系统在国内还有很大的发展空间。

  2 系统相关技术

 2.1 远程控制技术

 远程控制技术是指管理人员在异地通过计算机网络异地拨号或双方都接入Intetnet等手段,连接需被控制的计算机,将被控计算机的桌面环境显示到自己的计算机上,通过本地计算机对远方计算机进行配置、软件安装程序、修改等工作。通过远程控制技术可实现远程办公、远程教育、远程维护、远程协助等,提高工作效率和工作兴趣,实现高效率、低成本。

  2.1.1 远程控制流程

 远程控制系统通常由客户端和服务器端两部分组成,通过客户端和服务器端运行相应的程序来实现控制功能。系统实现的基本功能流程可以简化如下:

  1.服务器端运行相应的远程控制软件服务器程序,使服务器端的某个端口处于监听状态(本软件的默认端口设置为5150)。这样服务器端计算机就时刻处于监听远程计算机连接请求的状态。

  2.当服务器端程序运行后,客户端在本地计算机中运行相应程序的客户端程序,运行这个客户端程序时,会指定一个要连接的服务器的IP地址和端口,(本软件初始化的服务器地址是本地计算机的地址,端口是5150),程序运行后,点击连接就会向所有的网络搜索指定的计算机了。

  3.搜索到所指定的计算机后,客户端计算机就向服务器端指定的端口发送连接请求,如果服务器计算机同一端口处于监听状态,则服务器端接收客户端的连接请求,并根据设定的值向客户端发送接受请求确认信号。

  4.客户端输入登录信息确认后,就会向服务器端发送,服务器端接收到客户端发来的用户信息后,就开始对客户端所输入的用户进行合法性确认,如果不符合登录条件,则拒绝用户的连接。

  5.如果服务器端确认客户端所输入的用户符合服务器端计算机的条件,则服务器允许客户端进行一步的连接,这样,整个软件的连接过程就完成了。

  2.1.2 远程控制系统结构

 在远程控制系统设计中,通常采用典型的C/S结构,由客户端与服务器端两部分构成。客户/服务器模式的最显著特点是非对等作用,即客户端相对于服务器端处于不对称的地位,服务器端提供服务,客户端提供请求[8]。结构如图2.1。

  在设计客户端和服务器端时,由于功能需求不同,设计的客户端界面简单,面向对象,易于操作。而服务器端主要实现控制功能实现。而且不能让用户强行关闭,界面简单,而且做到隐藏。

  C/S结构的发展经历了两个阶段:从两层结构到三层结构。

  1.两层结构:它由两部分构成:前端客户机,通常是PC机,主要完成用户界面显示,接受数据输入,校验数据有效性,向后台数据库发请求,接受返回结果,处理应用逻辑;后端是服务器,运行DBMS,提供数据库的查询和管理。应用逻辑主要在前端,如在后端则是存储过程的形式。

 图2.1 C/S模型结构图

 2.三层结构:利用中间件将应用分为表示层、业务逻辑层和数据存储层三个不同的处理层次。根据逻辑上将应用划分为三个层次,具体的物理划分有较多组合种类。基于三层结构的应用系统不但具备了大型机系统稳定、安全和处理能力高等特性,同时拥有开放系统成本低、可扩展性强、开发周期短等优点。而中间件作为构造三层结构应用系统的基础平台,提供了几种主要功能:负责客户机与服务器间,服务器间与服务器间的连接和通信,实现应用与数据库的高效连接,提供一个三层结构应用的开发、运行、部署和管理的平台[9]。

  在设计远程控制系统客户端和服务器端时,由于功能需求不同,设计的客户端界面主要面向控制管理人员,应该具有良好的交互性,并且包含相应的帮助文件,易于管理人员操作。而服务器端主要实现控制功能,并且可以实现隐藏功能[10]。

  2.2 Socket技术

 C/S结构的原理是由一端提供服务,另一端接受服务。作为服务器的主机打开一个端口并进行监听,如果有客户端的请求。而Socket的正确使用给设计带来了极大的方便,使得各种应用程序能够在Windows环境下顺利进行各种网络通信[11]。

  2.2.1 Socket概念

 20世纪80年代初,美国政府的高级研究工程机构(ARPA)给加利福尼亚大学Berkeley分校提供资金,让他们在UNIX操作系统下实现TCP/IP协议。在这个项目中,研究人员为TCP/IP网络通信开发了一个应用程序接口(API)。这个API就称为Socket接口。今天,Socket接口是TCP/IP网络通用的API,也是在internet上进行应用开发最为通用的API[12]。

  一个套接口是通信的一端,在这一端上可以找到与其对应的一个名字。一个正在被使用的套接口都有它的类型和其相关的进程,套接口存在于通信域中。一个套接口通常和同一个域中的套接口交换数据。应用程序在网络上传输,接收的信息都通过这个套接口来实现。在应用开发中就像使用文件句柄一样,可以对Socket句柄进行读写操作。套接字编程主要包括网间进程通信和客户机/服务器模式两方面内容。

  进程通信的概念最初来源与单机系统。由于每个进程都在自己的地址范围内运行,为保证量相互通信的进程之间既互不干涉又能协调一致工作,操作系统为进程通信提供了相应设施,如

 UNIX BSD中和管道(Pipe)、命名管道(Named Pipe)和软中断信号(Signal)、UNIX System V的消息(Message)、共享存储区(Shared Memory)和信号量(Semaphone)等,但都仅限于用在本机进程之间的通信。网间进程通信要解决的是不同计算机进程间的相互通信问题(可把同机进程通信看成是其中的一个特例)。为此,首先要解决的是网间进程标识问题,同一计算机上,不同进程可以用进程号(Process ID)作为唯一标识,但在网络环境下,各个计算机独立分配的进程号不能唯一的标识该进程。例如,计算机甲赋予某进程号48,在乙计算机中也可以存在48号进程,因此,“48号进程”这句话就没有意义了。其次,操作系统支持的网络协议众多,不同的协议的工件方式不同,地址格式也不一样,因此,网间进程通信还要解决多重协议的识别问题[13]。

  在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式就是客户机/服务器模式(Client/Server)。即客户向服务发出服务请求,服务接收到请求后,提供相应的服务[14]。客户机/服务器模式的建立基于以下两点:首先,建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用:其次,网间进程通信完全是异步的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为两者的数据交换提供同步,这就是基于客户机服务器式的TCP/IP[15]。

  2.2.2 Socket类型

 1.流式套接字(SOCKSTREAM)

 流式套接字提供一种可靠的面向连接的传输方法。数据无差错,无重复地发送,而且按发送的顺序进行接收。不过对单个的数据报,还是对整个数据包,流式套接字都提供一种流式数据传输,流式套接字系在使用TCP。此外,在数据传输时,如果连接断开,应用程序会被通知。流式套接字内设流量控制,避免数据流超限,数据被看成字节流,无长度限制[16]。FTP使用这种套接字。

  2.数据报套接字(SOCKE_DGRM)

 数据报套接字提供一种不可靠的非连接的数据包(Packet)通信方式。在这里,“不可靠”是指发送一个数据包不能获得担保,也不能保证数据包按照发送的顺序到达目的地。数据包以独立形式被发送,不提供无错保证,数据可能丢失或重复,并且顺序混乱。在实现上,同一分组数据报可能不止一次的被发送。对于

 Socket的TCP/IP实现,数据报套接字使用用户数据报协议(UDP)。虽然在通常情况下,在局域网所连接的两台计算机的进程之间进行通信时,可能不会出现数据包不被发送或没按照顺序到达及又重复发送的情况,但在编写应用程序时,应该注意检测意外发生的事件,应具备处理出现这些情况的能力。当然,如果为非常复杂的网络编写通信应用程序,就应该考虑到数据报套接字的不可靠性。如果我们的应用程序没有处理好这个问题,它就有可能崩溃。尽管如此,数据报套接字在发送数据包或者记录数据时仍然有用。另外,数据报套接字还是提供向多个目的地发送广播数据包的能力。

  3.原始套接字(SOCKE_RAW)

 该接口允许对较低层协议,如IP,ICMP的直接访问。它通常用于检验新的协议实现或访问现有服务配置的新设备[17]。

  2.2.3 基本套接字函数调用

 首先,客户端和服务器端都要创建一个数据套接字。接着,服务器调用bind()函数给套接字分配端口(在开发应用程序时,这个公认的端口通常是指定的。例如本程序的端口就指定为5150。这样,客户端和服务器端都使用同一个端口用来表示服务器套接字。)一旦服务器将公认的端口分配给套接字,客户端和服务器端能使用sendto()和recvfrom()来发送和接收数据报直到完成传输。然后调用closeSocket()关闭套接字[18]。

  2.3 本章小结

 本章首先介绍了远程控制系统的功能实现流程,分析了C/S结构以及C/S结构发展阶段:从两层结构到三层结构。本章着重介绍了Socket技术,从Socket技术概念出发,介绍了Socket技术发展过程及各方面的应用。最后介绍了Socket技术的类型和基本套接字函数调用。

  浙江工业大学之江学院毕业设计(论文)                                                      

  3 系统需求分析

 3.1 系统功能模块

 随着计算机技术的不断发展,人们要处理的任务也越来越多。在计算机使用的过程中,可能会在多个工作地点,试图通过其它地方计算机使用和控制自己的计算机。本课题设计的使用,能帮助使用者远距离控制计算机,提高工作效率,降低成本。该设计采用二层C/S结构,在100Mps Ehternet校园网环境中进行[19]。通过IP和端口号来确定连接的服务器端,进行数据传输。以下将对系统各功能模块进行详细描述。

  3.1.1 客户端功能

 客户端主要包括三部分:监听连接,发送消息和监视屏幕。监听连接主要是监听服务器端是否开启连接。如开启连接,则发送连接请求;如未开启连接,则一直处于监听状态。发送消息是客户端向服务器端发送信息,实现远程控制功能。监视屏幕是通过发送屏幕数据监视服务器端的屏幕,以利于使用鼠标和键盘完全的控制服务器端。客户端主要功能如图3.1所示。

 图3.2 客户端功能模块图

 3.1.2 服务器端功能

 系统的控制功能主要由服务器端来实现。在服务器端,它们并不是主动地建立连接,而是通过监听被动地接受客户端的连接请求,并建立连接。客户端通过远程控制在服务器实现各个功能,包括主机管理,屏幕控制,系统管理,文件管理。主机管理包括监听主机,连接主机。屏幕控制包括键盘控制,鼠标控制,屏幕抓取。系统管理包括信息获取,信息修改,远程关机和远程重启。文件管理包括上传文件,下载文件,读取文件,删除文件,命名文件和创建文件。如图3.2所示。

  3.2 系统工作流程

 系统在工作时,首先调用Socket类的构造函数,以服务器的指定的IP地址或指定的主机名和指定的端口号为参数,创建一个Socket,负责监听客户端的请求。客户端在创建一个Socket的同时向服务器端发送服务连接请求,服务器端生成新的Socket

 ,原来的Socket仍处于监听状态。

  当服务器端接收到连接请求后,服务器端处理请求,分析是否空闲,如繁忙,则阻塞,如空闲则接受请求,服务器端与客户端建立连接,客户端发出控制写入,此时服务器Fork()出一个子进程专门处理该客户,完成服务器端与客户端的远程控制,实现客户端对服务器端的远程控制。完成整个操作后,父进程则关闭新的Socket,继续处理下一个客户进程。而服务器监听用的Socket对Fork出的子进程无用,所以子进程将其关闭,用产生的新Socket与客户交换信息,直到对方关闭此连接,子进程终止。关闭Socket。

  3.3 本章小结

 本章从C/S模式出发,通过图形介绍了客户端功能模块:监听连接、发送消息、监视屏幕和服务器端功能模块:主机管理、屏幕控制、系统管理、文件管理。同时,介绍了远程控制系统的详细工作流程。

 4 系统设计实现

 4.1 客户端设计

 客户端在工作时,首先向服务器端发送身份信息,请求与服务器建立连接,如果通过验证则定时发送屏幕控制数据,同时接受用户的输入并把其转换成相应的控制信息,然后发送到服务器端。在界面设计上,采用简洁明了的设计风格,如图4.1所示。

 图4.1 客户端界面示意图

 4.1.1 建立连接功能设计

 在通过远程网络控制通信时,首先要指定登录计算机的IP地址和端口号进行远程的控制连接,这样也具有更高的安全性。在客户端的连接中,通过CMainWnd::OnTimer()函数建立连接,如连接上,则显示新的屏幕;如未连接上,则选择菜单退出。最后关闭Socket,清除Socket。

  void CMainWnd::OnTimer(HWND hWnd,UINT iId)

 {

 // 如果连上了服务器

 if (fConnected)

 {

 // 得到一个新的屏幕

 GetScreen();

 }

 }

 // 处理WM_COMMAND消息

 void CMainWnd::OnCommand(HWND hWnd,int iId,HWND hWndCtl,UINT iCodeNotify)

 {

 // 选择菜单的退出

 if (iId == IDM_EXIT)

 {

 // 是否连上了服务器?

 if (fConnected)

 {

 // 发送结束消息到服务器

 memset(szMouseMessage,'\0',sizeof(szMouseMessage));

 strcpy(szMouseMessage,DISCONNECT_MSG);

 iSent = Send(sClient,szMouseMessage);

 // 关闭socket

 closesocket(sClient);

 // 清除socket

 4.1.2 发送消息功能设计

 定义两个字符串变量:m_csSend和m_csRead来实现客户端和服务器端的消息互连并且利用Send()函数来实现数据传输。返回的结果在信息显示窗口显示出来。通过CMainWnd::SetInstance()函数处理消息。

  void CMainWnd::SetInstance(HINSTANCE hInst)

 {

  m_hInst = hInst;

 }

 // 处理WM_CREATE消息。

  而且,在服务器端,利用了数组类自带的.mid()函数,提取主要的命令来实现对命令的筛选控制,更有利于服务器对客户端发送的命令的执行。

  4.1.3 屏幕控制功能设计

 屏幕控制是整个程序最主要和重要的功能模块,同时,不管是服务器,还是客户端,在实现远程屏幕监视方面都比较麻烦和复杂。在本程序里更是通过对屏幕的监视,才能进一步的控制远程计算机[20]。采用了通过服务器端抓取服务器端的桌面和图形,并且还有捕获鼠标和键盘的相应函数,一同通过服务器和客户端的Socket连接,发送到客户端。

  IntSelectProtocols(DWORDdwSetFlags,DWORD dwNotSetFlags,LPWSAPROTOCOL_INFOlpProtocolBuffer,LPDWORD lpdwBufferLength,WSAPROTOCOL_INFO *pProtocol);

 //LoadWinsock用来装载和初始化Winsock,绑定本地地址,创建监听Socket,等候客户端连接。

  在服务器端,要把抓出来的图形和键盘鼠标等相应函数联系起来,再捕获控制的鼠标键盘在服务器端图形显示区域里的响应以及相应的位置。在利用返回的鼠标键盘的函数操作,调用本地的鼠标键盘的函数操作,来实现对服务器端的控制。

  鼠标和键盘消息的相关程序如下:

  void DispatchWMMessage(char *szString)

 {

  //鼠标消息

  struct {char *szWMMouseMsg;}

 WMMouseMsg = {“WM_MM”,”WM_LBD”,”WM_LBU”,”WM_LBK”,

  “WM_MBD”,“WM_MBU”,“WM_MBK”,

  “WM_RBD”,“WM_RBU”,“WM_RBK”};

  // 键盘消息

  struct {char *szWMKeyBdMsg;}

  WMKeyBdMsg= {“WM_KD”,“WM_KU”};

 服务器端向客户端第一次发送获取屏幕命令时,客户端并非立即截屏然后将数据发送服务器端,考虑到多个客户端的屏幕分辨率大小不一致的情况下,客户端首次收到服务器端的屏幕监控命令后,应先将客户端当前屏幕分辨率发送给服务器端,服务器端在窗口上创建一个矩形区域用于显示客户端桌面图片,然后才是屏幕数据的传输。首先,创建屏幕的高度和宽度,确认接收等。由于客户端不停的发送屏幕数据,为了能使服务器端区分每一帧的屏幕,客户端在发送屏幕数据前,在屏幕数据尾部添加10个字节自定义的数据包,服务器端在每次接收数据后都会检验数据包尾部自定义的数据包,如果是在表示一帧图片传输完毕。

  客户端接收到服务器端桌面图片数据后,此时还不能将图片直接表示到窗口上,因为图片数据发送前是经过压缩的,因此应先解压,再将解压后的图片表示到窗口上,然后再发送请求下一帧桌面图片的请求。相关程序如下:

  void SendResolution(SOCKET MySocket)

 {

  char szMessage[81];

  DWORD iSent,iRecv;

  // 建立屏幕宽度

  memset(szMessage,‘\0’,sizeof(szMessage));

  sprintf(szMessage,“%d”,iWidth);

  iSent = Transmit(MySocket,szMessage,strlen(szMessage));

  // 接收确认

  memset(szMessage,‘\0’,sizeof(szMessage));

  iRecv = recv(MySocket,szMessage,81,0);

  szMessage[iRecv] = ‘\0’;

  // 建立屏幕的高度

  memset(szMessage,‘\0’,sizeof(szMessage));

  sprintf(szMessage,“%d”,iHeight);

  iSent = Transmit(MySocket,szMessage,strlen(szMessage));

  // 接收确认

  memset(szMessage,‘\0’,sizeof(szMessage));

  iRecv = recv(MySocket,szMessage,81,0);

  szMessage[iRecv] = ‘\0’;

 }

 // 通过Socket发送区域显示位图

 IntSelectProtocols(DWORDdwSetFlags,DWORD dwNotSetFlags,LPWSAPROTOCOL_INFOlpProtocolBuffer,LPDWORD lpdwBufferLength,WSAPROTOCOL_INFO *pProtocol)

 //LoadWinsock用来装载和初始化Winsock,绑定本地地址,创建监听Socket,等候客户端连接

 为了减小CPU的利用率,禁止在Socket上将数据发送到缓冲。设置SO_SNDBUF为0, 从而使winsock直接发送数据到客户端,而不是将数据缓冲才发送。

  客户端线程函数,这个函数等候从客户端程序发送过来的消息,

 如果这个消息是“REFRESH”,那么它发送当前的桌面图片;

 如果这个消息是“DISCONNECT”,那么它结束和客户端的连接;

 如果这个消息以“WM_”开头,那么它就根据消息类型,在服务器端执行该消息。

  4.2 服务器端设计

 服务器端程序是远程控制软件的主体,是远程控制软件的主体。远程控制软件的具体功能都是在服务器端实现的,客户端只负责传送要执行的命令和显示返回的结果。而几乎所有的操作控制都是在服务器端实现的。远程控制的服务器端要求运行相关程序,同时还应该要具有一定的隐藏性,不容易客户端用户发现和关闭。故界面简单,并且在设置好IP地址和端口号后,可以点击确定键,隐藏界面,如图4.2

 所示。

 图4.2 服务器端界面示意图

 在设计服务器端向客户端传送数据时使用霍夫曼压缩方法压缩图片。霍夫曼压缩方法是1952年为文本文件建立的,其基本原理是频繁使用的数据用较短的代码代替,很少使用的数据用较长的代码代替,每个数据的代码各不相。这些代码都是二进制码,且码的长度是可变的。如:有一个原始数据序列,ABACCDAA则编码为A(0),B(10),C(110),D(111),压缩后为010011011011100。产生霍夫曼编码需要对原始数据扫描两遍,第一遍扫描要精确地统计出原始数据中的每值出现的频率,第二遍是建立霍夫曼树并进行编码,由于需要建立二叉树并遍历二叉树生成编码,因此,数据压缩和还原速度都较慢,但简单有效,因而得到广泛的应用。

  4.2.1 主机监听功能设计

 服务器端Socket自一开始运行就一直保持监听状态,等待来自客户端的连接。首先进行Socket初始化,得到本地的IP和端口号,再通过ServerDlg::OnSysCommand()进行监听。

  m_hMenu = ::GetMenu(m_hWnd);

  EnableMenuItem(m_hMenu,IDM_STARTSERVER,MF_BYCOMMAND|MF_ENABLED);

  EnableMenuItem(m_hMenu,IDM_STOPSERVER,MF_BYCOMMAND|MF_GRAYED);

  // Winsock初始化的地方

  WSADATA

 wsd;

  char

 szString[255];

  char

 name[20];

  // 装入Winsock2.2版本

  if (WSAStartup(0x202,&wsd) != 0)

  {

 sprintf(szString,"Failed to load Winsock!");

 ::MessageBox(NULL,szString,"Remote Server",MB_OK);

 return 1;

  }

  //得到本机的IP地址

  GetLocalHostName(name);

  GetIpAddress(name,&m_ip[0],&m_ip[1],&m_ip[2],&m_ip[3]);

 void ServerDlg::OnSysCommand(UINT nID, LPARAM lParam)

 {

  if ((nID & 0xFFF0) == IDM_ABOUTBOX)

  {

 CAboutDlg dlgAbout;

 dlgAbout.DoModal();

  }

  else

  {

 CDialog::OnSysCommand(nID, lParam);

  }

 }

 4.2.2 鼠标键盘控制功能设计

 在本软件中,客户端可以通过网络控制服务器端的计算机的鼠标和键盘,已达到远程控制服务器端的目的,鼠标是一个定位输入设备。要控制鼠标就要控制鼠标所在的屏幕位置并控制鼠标的按键操作。要实现鼠标操作,首先就要了解几个和鼠标操作有关的函数和结构。下面介绍这些函数和结构。

  1.mouse_event()函数,其原型如下:

  void mouse_event (DWORD dwFlage,DWORD dx,DWORD dwData,DWORD dwExtrainfo);

 函数mouse_event()可用来对鼠标进行移动和按键操作。

  2.Sendinput()函数

 Sendinput函数集成了键盘按键,鼠标移动和按键操作。

  3.Input结构

 Input结构定义如下:

  Typedef struct tagINPUT

 {

 DWORD type;

 Union 

 {

 MOUSEINPUT   mi;

 KEYBDINPUT    ki;

 HARDWAREINPUT   hi;

       }

      } INPUT,*PINPUT ,FAR *LPINPUT;

 其中成员type指明输入事件的类型,可以取以下值。

  (1)INPUT_MOUSE:鼠标事件,使用联合体的mi结构。mi结构的定义如下:

  Typedef struct tagMOUSEINPUT

 {

 LONG dx;

 LONG dy;

 DWORD mouseData;

 DWORD dwFlags;

 DWORD time;

 DWORD dwExtraInfo;

 }MOUSEINPUT ,*PMOUSEINPUT,FAR*LPMOUSEINPUT;

 成员变量类似前面的mouse_event()函数的参数。

  (2)INPUT_KEYBOARD:键盘事件,使用联合体ki结构。定义如下:

  Typedef struct tagKEYBDINPUT

 {

 WORD wVk;

 WORD wScan;

 DWORD dwFlags;

 DWORD time;

 DWORD dwExtraInfo;

 }KEYBDINPUT,*PKEYBDINPUT,FAR *LPKEYBDINPUT;

 其中成员wVk指定按键的虚拟键值,取值范围为1~254。

  4.SetCursorPos()函数移动光标到指定位置。如果指定的位置超出屏幕。在系统会自动调整光标的位置能在屏幕范围内。

  原型声明如下:

  BOOL SetCursorPos(int X ,int Y);

 5.GetCursorPos()函数获取光标位置,原型声明如下:

  BOOL GetCursorPos(LPPOINT lpPoint);参数lpPoint指向一个接收屏幕坐标的结构体。如果调用成功,函数返回一个非0值,否则,返回0值;

 6.OnMouseMove()函数

 函数OnMouseMove()原型如下:

  afx_msg void onMouseMove(UINT nFlags,CPOINT point);

 当鼠标在窗口移动时,调用该函数,OnMouseMonve()函数有两个参数。nFlags指明是否有按键按下。

  4.2.3 屏幕抓取功能设计

 在远程控制的实践中,客户端用户要想知道服务器端的用户在干什么,一般有两种方法,一种方式是记录服务器端的键盘和鼠标,形成一个文本文件,然后把文件发到客户端。客户端用户通过查看文件的方式了解服务器端的用户打开了哪些程序,敲哪些键。这样,虽然知道了用户的一些操作,但是不直观,而且查阅起来也不方便。这时就用到另一种方式。另一种方式是在服务器端抓取当前的屏幕,形成位图文件,然后把该文件发送到客户端计算机并显示出来,实现抓取远程屏幕。

  实现远程抓取屏幕,必须了解位图和与其相关的结构体。如下所示:

  1.RECT结构

 Typedefstruct tagRECT

 {

 LONG left;//左上角的X坐标

 LONG top;//左上角的Y坐标

 LONG right;//右下角的X坐标

 LONG bottom;//右下角的Y坐标

 }RECT;

 2.BITMAP结构

 typedef struct tagBITMAP

 {

 int bmType;//指定位图类型,对于逻辑位图,该值为0

 int bmWidth;//指定位图的宽度,以象素为单位,该值必须大于0。

  int bmHeight;//指定位图的高度。以象素为单位,该值必须大于0。

  int bmWidthBytes;//指定每条光栅所占的字节数。该值必须取偶数,

 BYTE bmPlanes;//位图调色板颜色数

 BYTE bmBitsPixel;//一个点在美国调色板上接近的颜色位数

 LPVOID bmBites;//位图的位值的地址指针

 }BITMAP;

 3.BITMAPFILEHEADER结构

 该结构定义了包含设备独立位图的文件类型、大小和文件布局。通常在使用时,后面紧跟BIMAPINFO结构。定义如下:

  typedef struct tagBITMAPFILEHEADER

 {

 WORD bfType;//文件类型,不想取BM

 DWORD bfSize;//位图文件的大小,以字节位单位

 WORD bfReserved1;//保留,必须为0

 WORD bfReserved2;//保留,必须为0

 DWORD bfoffBits;//知道BITMAPFILEHEADER结构到位图位值之间的偏移量以字节为单位

 }BITMAPFILEHEADER;

 4.2.4 信息获取和修改功能设计

 在远程控制软件中,客户端可以通过软件获得服务器端的计算机的一些基本信息,例如内存信息和操作系统信息等;也可以修改被控制端计算机的系统配置,获得系统信息通过系统API来实现,修改系统配置有两种方式,一种是直接修改系统配置文件,包括win.ini,system.ini,system.sys和autoexec.bat等文件;另一种方式就是修改系统的注册表。本软件在修改系统配置的时候,只是单纯查看和配置系统文件,和手工修改文本来实现这个功能,而且,出于安全考虑,并不想通过修改服务器端的系统配置而使服务器端系统崩溃等。

  本程序只设置了int_chdir(const char*dirname);//改变当前目录;

 int_chdir( int drive);//改变当前驱动器;

 char*_getcwd(char*buffer,int maxlen);//读取当前目录;

 char*_getcwd( int driver,char*buffer,int maxlen );//从指定驱动器的读取当前目录;

 int_mkdir( const char*dirname );//建立目录;

 int_rmdir( const char*dirname );//删除目录。

  DOS在启动会自动运行autoexec.bat这条文件,一般我们在里面装载每次必用的程序,如:path(设置路径)、smartdrv(磁盘加速)、mouse(鼠标启动)、mscdex(光驱连接)、doskey(键盘管理)、set(设置环境变量)等。这些都是系统信息存储的重要信息,一般不要改动。CONFIG..SYS也是DOS系统中的一个重要文件,它的配置直接影响到系统的使用及其效率。如果配置不当,很容易导致服务器端的系统崩溃。

  4.2.5 远程关机和重启功能设计

 在远程控制软件中,有时需要重启服务器端,或者强制关闭远程计算机。例如,在远程教学中,当老师发现远程学生不是在浏览与本课程有关的内容甚至玩游戏时,可以先发送消息给予警告,如果学生还是不听,老师就可以强行使学生的计算机重启,或者强行关机。

  本系统中,客户端给服务器端发送有关命令,服务器端收到命令后,再执行相应的操作。其实,所有的操作都是在服务器端执行的,这些操作都主要使用一个主要的函数ExitWindowsEx()来实现的,这个函数原型如下:

  BOOL ExitWindowsEx(UINT uFlags,DWORD dwReserved);

 调用函数成功,则ExitWindowsEx()返回一个非0值,否则,返回0。如果要实现这些功能,则要调用GetVersion()函数来获取操作系统的版本,当操作系统是Windows 2000或以上时,则需要设置调用进程的权限,使之能进行重新启动计算机等相关操作。

  4.2.6 文件管理功能设计

 在远程控制中,文件的管理主要包括文件的上传与下载,删除文件,目录浏览,文件更名,更改文件属性和执行文件等。如果通过读取文件并发送到客户端来实现这些功能,相对简单。但是,这些功能可以通过FTP(文件传输协议)功能来实现。在该程序中使用了FTP功能来实现这些模块。

  要利用FTP功能实现这些功能,首先要与FTP服务器建立连接,连接方法通常有两个步骤,下面就介绍用FTP功能实现的好处。首先需要建立一个ClnternetSesion对象,用类ClnternetSesion创建并初始化一个网络会话,并描述与代理服务器的连接,如果要在程序运行期间需要保持与网络的连接,可以创建一个ClnternetSesion对象作为CWinApp的成员。

  MFC中的类CFtpConnection管理与网络服务器的连接,并直接操作服务器上的目录和文件,FTP是MFC的WinInet支持的三个网络功能之一,这里只需要创建一个ClnternetSession实例和一个CFtpConnection对象,就可以实现和一个FTP服务器的通信了,它是通过调用ClnternetSession::GetFtpConnection来完成这项工作的,它创建了CFtpConnection对象并返回一个指向该对象的指针。故不需要再次创建CFtpConnection对象。

  1.文件清单

 列文件目录清单如果用文件来实现起来较为复杂,但是利用到FTP技术以后,实现起来就简单化了,通过调用关于FTP技术的相关函数,可以实现这个操作。主要是用到了文件操作:首先设置一个用来存储当前的目录的系统目录数组,再创建两个暂时存储系统目录和临时文件的临时数组,连接套接字后,得到系统的目录,再把列表的目录设置为当前的目录,然后执行文件操作,查找文件,获得文件性质,并且把查到的文件名,文件名存储成一个文本形式并按“文件名、大小、时间”的格式发送到客户端的窗口。

  2.读写文件内容

 在实现查看文件内容文件操作没有利用到FTP服务器。文件传输等功能的实现也可以不用FTP技术,直接用Socket进行数据传送。如果要拷贝文件,只需要将接收到的数据转化为文件即可。本模块的实现是建立一个CFile对象,通过对这个对象的打开,读取等操作,将读到的文件内容保存在一个临时数组里,然后通过定义的服务器反馈函数将临时数组里的数据发送到客户端的窗口。函数原型如下:

  Int fgetc ( file *stream );

 Int getc ( file *stream );

 Int fputc ( int c, file *stream );

 Int putc ( int c, file *stream );//从文件中读一个字符,或向文件中写一个字符。

  Char *fgets ( char *string, int n, file *stream );

 Int fputs ( const char *string, file *stream );//文件字符串读写。

  3.文件传输

 本程序的文件传输功能利用了FTP技术。如果要拷贝的文件过大,用文件操作来实现时,就要预设一个很大的数组来暂时存储文件,这样会使很大部分的内存空间浪费掉,使文件传输速度很慢。如果网络条件不好,容易使文件传输中出现断掉,毁坏文件的情况。本来可以用查看文件内容的方式来实现这项技术,但是同时,为了显示文件传输的多元性,使用了FTP技术。拷贝文件其实是上传到本地的服务器端,传输文件到客户端实际上是受控端从本地服务器端上下载这个文件。函数原型如下:

  Char *strcpy ( char *strDestination, const char *strSource );

 Char *strcnpy ( char *strDest, const char *strSource, size_t count );//字符串拷贝。

  4.信息的获取及修改

 在一般的运程控制软件中,控制端用户可以通过软件获得服务器端的计算机的一些基本信息,例如内存信息和用户名等,也可以修改服务器端计算机的系统配置,获得系统信息通过系统

 API来实现,修改系统配置有两种方式,一种是直接修改系统配置文件,包括win.ini,system.ini,system.sys等文件;另一种方式就是修改系统的注册表。函数原型如下:

  Int_ rename ( const char*oldname, const char*newname );//修改文件名;

 Int_ unlink ( const char*filename );//删除文件,原型在头文件Stdio.h和io.h中。

  4.3 本章小结

 本章介绍了远程控制系统的具体功能。在这些功能中,屏幕控制是这些功能的核心功能,同时通过鼠标和键盘等输入设备实现各个功能。在系统控制功能设计和文件管理功能中,主要通过调用函数实现各个功能。同时为了系统的效率和稳定性,也使用了FTP等技术。

推荐访问:控制系统 毕业论文 通信

《基于Socket通信的远程控制系统设计-毕业论文.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:

文档为doc格式

一键复制全文 下载 投诉