计算机论文代写精彩选文:计算机远程控制

发布时间:2012-04-24 13:24:00 论文编辑:代写硕士论文

计算机远程控制
 
【摘要】
在如今这个信息高速发达的时代,人们之间的物理距离虽无太大变化,然而逻辑距离却在一天天缩小。同时,鉴于交通的繁忙,无纸办公和远程办公的趋势已然愈演愈烈!远程控制应运而生。
本文首先介绍了系统分析方面的一些内容,紧接着开始介绍实现远程控制基础——Socket编程的基本概念,以及Windows的消息系统,接着从建立Socket套接字开始,经过逐个功能模块的分析实现,从命令控制到文件下载,到屏幕控制等。然后重点介绍了屏幕控制和文件下载功能。
本系统在文件下载方面,采用了文件流stream的方式进行文件传输,首先是通过命令控制中的dir命令,获得文件路径和文件名,然后将文件名传到服务器端进行下载。在屏幕控制方面,是由客户端发送命令src到服务器端,服务器响应后,进入相应的通讯进程。 客户端发出获取服务器屏幕图像数据的请求,把从服务器接收到的图像在本地实时显示出来,并且及时发送鼠标在本地显示图像的动作给服务器。服务器则主要负责响应客户端的请求并抓取与发送屏幕图像,响应客户端发送过来的鼠标、键盘等的动作并反馈给客户端。从而实现了对远程计算机的直接控制。

【关键词】 :C\S、Socket、TCP\IP、流

Abstract:
Now in this information era of high-speed developed the physical distance between people, although do not have too big change, however logical distance but by 
narrowing. At the same time, given the busy traffic, the paperless office and telecommuting trend has intensified. Remote control arises at the historic moment.
With the rapid development of network technology and popularization of the network in all trades and professions, remote control technical support will gradually occupy the mainstream technical support. This article is about a Windows based remote control system developed by use of the network programming, the most common Socket technology and multi-thread programming, etc. And the remote control involves the technology and method for grade function prototype detailed explanation, can easily understand.
This paper first introduces to realize the remote control basics Socket basic concepts of programming, and the message system, then Windows Socket from establishing one begins, goes through the analysis of the functional modules from the command control to realize, file download, to screen control etc. Then mainly introduces screen control and file download function.
This system in file download aspects, using a document flow stream way file transfer, first is through the dir command, command and control get file path and filename, then will filename to the server to download. In the screen control, is by the client sends commands SRC to the server, server response, into the corresponding communication process. The client access server screen image data sent from the request, the server receives images in the local real-time display out, and timely send the mouse in local display images action to the server. The server is mainly responsible for response to client request and grab and send a screen image, response to a client sending over the mouse, keyboard actions and feedback to the client. And thus realizes the direct control of the remote computer. 

Key Words:C\S、Socket、TCP\IP、Stream
 
目录
引言 1
系统分析 3
系统需求分析 3
1.2系统功能分析 4
1.3系统软件模型 5
二、系统体系结构设计 5
2.1 基本控制原理 5
2.2 命令控制模块 6
2.3 屏幕控制模块 6
2.4 鼠标控制模块 6
2.5 键盘控制模块 6
2.6 文件下载模块 7
三、远程控制系统的实现 7
3.1 Socket技术基本原理 7
3.1.1 Socket背景 7
3.1.2 Socket的三种类型 9
3.1.3  Socket类中的常规函数调用 10
3.2 .NET中的Socket编程 13
3.3 客户端实现 14
3.3.1客户端界面设计 15
3.3.2  连接远程主机 15
3.3.3 发送命令 15
3.3.4 直接控屏 16
3.3.5 帮助 18
3.4 服务端实现 18
 

3.4.1 进行监听、时刻准备连接 19
3.4.2 程序设置自动运行 19
3.4.3 查看文件内容 20
3.4.5 文件下载 21
3.4.6 远程屏幕抓取的实现 21
四、总结 22
结  论 22
参考文献: 23
致   谢 24

引言
随着计算机网络的飞速发展以及网络技术的日益普及和大众化,人们可以很方便地从Internet上获取和自己工作生活密切相关的信息,世界也真正变成一个地球村,我们可以和世界上其他任何一个人通过计算机网络进行沟通,信息资源达到了高度的共享。从这一点得到启发,希望能设计一个远程控制系统,通过它可以在家里控制办公室里的计算机。如果你是软件开发商,你的员工可以通过它在办公室里远程为客户配置系统、对产品进行维护,如果客户向你报告软件产品出现问题你可以远程对产品进行调试,最终解决问题。这样员工就不会因长期的劳苦奔波而抱怨,用户也不会因为你不能及时解决问题而和你讨价还价,当然,也为公司节约了人力、财力和物力。
远程控制是在网络上由一台电脑(主控端/客户端)远距离去控制另一台电脑(被控端/服务器端)的技术,这里的远程不是字面意思的远距离,一般指通过网络控制远端电脑,不过,大多数时候我们所说的远程控制往往指在局域网中的远程控制而言。当操作者使用主控端电脑控制被控端电脑时,就如同坐在被控端电脑的屏幕前一样,可以启动被控端电脑的应用程序,可以使用被控端电脑的文件资料,甚至可以利用被控端电脑的外部打印设备(打印机)和通信设备(调制解调器或者专线等)来进行打印和访问互联网,就像你利用遥控器遥控电视的音量、变换频道或者开关电视机一样。不过,有一个概念需要明确,那就是主控端电脑只是将键盘和鼠标的指令传送给远程电脑,同时将被控端电脑的屏幕画面通过通信线路回传过来。也就是说,我们控制被控端电脑进行操作似乎是在眼前的电脑上进行的,实质是在远程的电脑中实现的,不论打开文件,还是上网浏览、下载等都是存储在远程的被控端电脑中的。
计算机中的远程控制技术,始于DOS时代,只不过当时由于技术上没有什么大的变化,网络不发达,市场没有更高的要求,所以远程控制技术没有引起更多人的注意。但是,随着网络的高度发展,电脑的管理及技术支持的需要,远程操作及控制技术越来越引起人们的关注。远程控制一般支持下面的这些网络方式:LAN、WAN、拨号方式、互联网方式。此外,有的远程控制软件还支持通过串口、并口、红外端口来对远程机进行控制(不过,这里说的远程电脑,只能是有限距离范围内的电脑了)。传统的远程控制软件一般使用NETBEUI、NETBIOS、IPX/SPX、TCP/IP等协议来实现远程控制,不过,随着网络技术的发展,目前很多远程控制软件提供通过Web页面以JAVA技术来控制远程电脑,这样可以实现不同操作系统下的远程控制,例如数技通科技有限公司推出的全球第一套基于中文JAVA的跨平台远程控制软件——易控。
远程控制软件一般分两个部分:一部分是客户端程序Client,另一部分是服务器端程序Server,在使用前需要将客户端程序安装到主控端电脑上,将服务器端程序安装到被控端电脑上。它的控制的过程一般是先在主控端电脑上执行客户端程序,像一个普通的客户一样向被控端电脑中的服务器端程序发出信号,建立一个特殊的远程服务,然后通过这个远程服务,使用各种远程控制功能发送远程控制命令,控制被控端电脑中的各种应用程序运行,我们称这种远程控制方式为基于远程服务的远程控制。通过远程控制软件,我们可以进行很多方面的远程控制,包括获取目标电脑屏幕图像、窗口及进程列表;记录并提取远端键盘事件(击键序列,即监视远端键盘输入的内容);可以打开、关闭目标电脑的任意目录并实现资源共享;提取拨号网络及普通程序的密码;激活、中止远端程序进程;管理远端电脑的文件和文件夹;关闭或者重新启动远端电脑中的操作系统;修改Windows注册表;通过远端电脑上、下载文件和捕获音频、视频信号等。
前面所讲的是一台电脑对一台电脑的情况,其实,基于远程服务的远程控制最适合的模式是一对多,即利用远程控制软件,我们可以使用一台电脑控制多台电脑,这就不必为办公室的每一台电脑都安装一个调制解调器,而只需要利用办公室局域网的优势就可以轻松实现远程多点控制了。在进行一台电脑对多台远端电脑进行控制时,远程控制软件似乎更像一个局域网的网络管理员,而提供远程控制的远程终端服务就像极了办公室局域网的延伸。这种一对多的连接方式在节省了调制解调器的同时,还使得网络的接入更加安全可靠,网络管理员也更易于管理局域网上的每一台电脑。
远程控制具有一下优点:便于用户能够在任何地方通过网络及时,快速的访问,控制自己的主机。特别是对于网络管理员,技术服务人员来说,远程控制提供了一个便捷,高效的手段。
当然,远程控制软件是一把双刃剑,有优点就会有缺点,它存在比较严重的安全隐患。一方面给用户和网络管理员工作带了很大的方便,另一方面也给一些居心不良者留下后门。形成很多木马程序。这就需要对软件在设计方面做一些安全考虑。

系统分析
1.1系统需求分析
如今的网络,可以说已经覆盖了各行各业,不论是有这方面基础知识的,还是没有的,都在使用它。这样一来,在使用过程中,就难免会出些问题,有能力解决的,自然无所谓。而那些不具备解决这方面问题能力的人或企业,在出了问题之后则会显得相对紧张些,甚至是恐慌。因为企业的运转与这方面是紧密相连的,它出了问题,企业也就如机器失去电源般,无法运转了。这个时候,企业自然会想到软件提供商们,而这样的问题由他们来负责解决也确实无可厚非。但是,那些软件提供商们,总不能一天到晚常驻这些企业里,因此正常解决起来,并没有想象中那么及时。可是,如果我们拥有远程控制的话,一切就迎刃而解了。通过远程控制,软件提供商方面的技术人员,可以在自己的办公室里操作企业的机器,从而解决问题。为企业减少了损失,也为自己减少了一些不必要的开支,还能提升自己在客户心目中的企业形象,一举数得,何乐而不为?
远程控制,顾名思义,就是像操作自己电脑一样,去远距离操控另一台电脑。很显然,这样的系统,一般就是采用C/S模式或者B/S模式。
网络应用程序的基本开发模式是C/S模式,其系统结构式指把一个大型的计算机应用系统变为多个能互为独立的子系统。服务器是整个应用系统资源的存储与管理中心,多台客户机则各自处理相应的功能,共同实现完整的应用。C/S模式一般基于传输层的TCP协议实现。主要特点是交互性强、具有安全的存取模式、网络通信量低、相应速度快、利于处理大量数据。但该结构的程序是针对性开发,变更不够灵活,维护和管理的难度较大,通常只局限于小型局域网,不利于扩展,分布功能弱且兼容性差,缺少通用性。要求具有一定专业水准的技术人员去完成。
而B/S模式则是一种特殊的C/S模式,它用通用的浏览器程序和Web服务器分别代替了专用的客户端程序和服务器端程序,简化了C/S模式的应用。B/S模式简化了客户端,不需要在客户端安装特定应用程序,系统维护只需在Web服务器端进行,分布性强、维护方便、可扩展性好。但是B/S模式的实现是基于应用层的HTTP协议,传输数据中包含了大量的传输控制信息,有效数据的传输效率较低,数据安全性不强,不能满足远程控制系统在性能方面的要求。
因此,相较之下,本系统采用C/S开发模式(Client/Server)。它由客户端与服务端两部分构成。客户/服务器模式的最显著特点是非对等作用,即客户相对于服务器处于不平等的地位,服务端提供服务,客户端提供请求。其系统结构如下图1所示:

1.2系统功能分析
本软件是由客户端和服务器端两部分组成的。而且需要客户端和服务器端同时运行相应的程序来实现。本软件要实现的基本功能可以简化如下:
第一步,服务器端运行相应的远程控制软件服务器程序,使服务器端的某个端口处于监听状态(本软件端口设置为7068)。这样服务器端计算机就时刻处于监听远程计算机连接请求的状态。
第二步,当服务器端程序运行后,客户端在本地计算机中运行相应程序的客户端程序,运行这个客户端程序时,会指定一个要连接的服务器的IP地址和端口,(本软件要求输入服务端IP地址,端口是默认的7068。原则上不允许用户更改端口),程序运行后,点击连接就会向所在网络搜索指定的计算机了。
第三步,搜索到所指定的计算机后,客户端计算机就向服务器端指定的端口发送连接请求(本软件使用TCP连接),如果服务器端计算机同一端口处于监听状态,则服务器端接收客户端的连接请求,并根据设定的值向客户端发送接受请求确认信号,并同时向客户端发出登录成功信息,客户端显示连接成功确认对话框。
第四步,连接成功后,就可以进行命令控制、屏幕控制以及文件下载了。

1.3系统软件模型
在本软件设计中,采用典型的C/S结构,由客户端与服务端两部分构成。客户/服务器模式的最显著特点是非对等作用,即客户相对于服务器处于不平等的地位,服务端提供服务,客户端提供请求。

二、系统体系结构设计
2.1 基本控制原理
该远程控制系统由服务器端和客户端两个部分组成,客户端可以通过鼠标和键盘以及相应的命令控制服务器端的计算机。 实现远程控制的机理是,受控机运行一个程序,用于侦听端口并接受数据包,而控制方通过端口给受控方的端口发送数据包。一共需编写两个程序,一个是控制方,另一个则是受控方,受控机等待控制机发送过来的指令然后执行相应的操作。

2.2 命令控制模块
此模块直接接受DOS命令,另外自定义了三个命令src(屏幕控制)、Close(关闭套接字)和DownLoad(文件下载)。

2.3 屏幕控制模块
可以让客户端用户实时监控服务器端计算机的运行状态。客户端以一定的频率向服务器发送请求,服务器响应客户端的请求将自己的屏幕拷贝下来并将这些信息发送给客户端,客户端接收到这些信息之后以图像的形式显示出来,为鼠标和键盘控制提供图形化接口。

2.4 鼠标控制模块
可以让客户端用户通过鼠标控制服务器端的计算机。其实现过程是客户端软件先捕捉鼠标在图形化接口(屏幕控制模块提供的)中的动作,再将这些信息发送到服务器端,最后服务器端的服务程序向操作系统(并不是自己处理)发送这个动作的消息,这样就如同在服务器端的操作系统上进行了相应的鼠标操作。

2.5 键盘控制模块
可以让客户端用户通过键盘控制服务器端计算机的输入,其实现过程是客户端软件先捕捉键盘在图形化接口中的动作,再将这些信息发送到服务器端,服务器端的服务程序向操作系统发送这个动作的消息,这样就如同在服务器端的操作系统上进行了相应的键盘输入。这样一来,如果服务器端的“Microsoft Word”为当前的活动窗口,则客户端的键盘操作就如同有人在服务器端利用“Microsoft Word”进行文字编辑一样。屏幕控制、键盘控制和鼠标控制模块是在网络状况较好的情况下才会有较快的响应速度,如果网络状况不好将采用命令控制模块进行远程控制模块进行远程控制。这种控制方式有较多的限制,需要根据具体的需求进行设计。

2.6 文件下载模块
可以让客户端用户下载服务端的相关文件。客户端用户,只需传一个文件路径至服务端,软件会自动给文件路径加上前缀”download_”,服务器端收到带前缀”download_”的消息时,便会自动去解析文件名并下载至用户指定的客户端文件路径中。整个系统结构如下所示:

三、远程控制系统的实现
3.1 Socket技术基本原理
网络客户/服务器模式的原理是一台主机提供服务(服务器),另一台主机接受服务(客户机)。作为服务器的主机打开一个端口并进行监听, 如果有客户机向服务器的这一端口提出连接请求, 服务器上的相应程序就会自动运行,来应答客户机的请求。而Socket的正确使用,给设计者带来了极大的方便,使得各种应用程序能够在Windows环境下顺利进行各种网络通讯。

3.1.1 Socket背景
20世纪80年代初,美国政府的高级研究工程机构(ARPA)给加利福尼亚大学Berkeley分校提供资金,让他们在UNIX操作系统下实现TCP/IP协议。在这个项目中,研究人员为TCP/IP网络通信开发了一个应用程序接口(API)。这个API就称为Socket接口。今天,Socket接口是TCP/IP网络最通用的API,也是在Internet上进行应用开发最为通用的API。
实际上,Socket在计算机中提供了一个通信端口(ip:port)。通过这个端口,一台计算机可以与任何一台具有Socket接口的计算机通信。通信的基础是套接字。一个套接字是通信的一端,在这一端上可以找到与其对应的一个名字。一个正在被使用的套接字都有它的类型和与其相关的进程,套接字存在于通信域中。一个套接字通常和同一个域中的套接字交换数据(数据交换也可以穿越域的界限,但这时一定要执行某种解释程序)。应用程序在网络上传输、接收的信息都通过这个套接字来实现。在应用开发中就像使用文件句柄一样,可以对Socket句柄进行读写操作。
开始使用套接字编程之前,首先必须建立这些概念:网间进程通讯,服务方式,客户机/服务器模式。
进程通信的概念最初来源于单机系统。由于每个进程都在自己的地址范围内运行,为保证相互通信的进程之间既互不干涉又能协调一致工作,操作系统为进程通信提供了相应设施,如UNIX BSD中的管道(Pipe)、命名管道(Named Pipe)和软中断信号(Signal)、UNIX System V的消息(Message)、共享存储区(Shared Memory)和信号量(Semaphore)等,但都仅限于用在本机进程之间的通信。网间进程通信要解决的是不同计算机进程间的相互通信问题(可把同机进程通信看成是其中的一个特例)。为此,首先要解决的是网间进程标识问题,同一计算机上,不同进程可以用进程号(Process ID)作为唯一标识,但在网络环境下,各个计算机独立分配的进程号不能唯一的标识该进程。例如,计算机甲赋予某进程号45,在乙计算机中也可以存在45号进程,因此,“45号进程”这句话在网间计算机中就没有意义。其次,操作系统支持的网络协议众多,不同协议的工作方式不同,地址格式也不一样,因此,网间进程通信还要解决多重协议的识别问题。
在网络分层结构中,各层之间是严格单向依赖的,各个层次的分工和协作集中体现在相邻层之间的界面上。“服务”是描述相邻层之间关系的抽象概念,即网络中各层向紧邻上层提供一组操作。下层是服务提供者,上层是请求服务的用户。服务的表现形式是原语(Primitive),如系统调用或库函数等。系统调用是操作系统内核向网络应用程序或高层协议提供的服务原语。在国际标准化组织(ISO)的术语中,网络层及其以下各层又称为通信子网,只是提供点到点的通信,没有程序或进程的概念。而传输层实现的是“端到端”通信,引进网间进程通信概念,同时也要解决差错控制、流量控制、数据排序(报文排序)及连接管理等问题。为此提供不同的服务方式:面向连接(虚电路)的服务或无连接的服务。面向连接服务是电话系统服务模式的抽象,即每一次完整的数据传输都要经过建立连接,使用连接及终止连接的过程。在数据传输过程中,各数据分组不携带目的地址,而使用连接号(Connect ID)。本质上,连接是一个管道,收发数据不但顺序一致,而且内容相同。其中TCP协议就提供面向连接的虚电路。无连接的服务是邮政系统服务的抽象,每个分组都携带完整的目的地址,各分组在系统中独立传送。无连接服务不能保证分组的先后顺序,不进行分组出错的恢复与重传,不保证传输的可靠性。提供无连接的数据报服务的常用协议是UDP协议。
    在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式就是客户机/服务器模式(Client/Server)。即客户向服务发出服务请求,服务接收到请求后,提供相应的服务。客户机/服务器模式的建立基于以下两点:首先,建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用;其次,网间进程通信完全是异步的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为两者的数据交换提供同步,这就是基于客户机/服务器式的TCP/IP。

3.1.2 Socket的三种类型
TCP/IP的Socket提供流式套接字、数据报套接字、原始套接字三种。

3.1.2.1  流式套接字(STREAM)
如果我们想让发送出去的数据按顺序无重复地到达目的地,那么就需要使用流式套接字。流式套接字提供一种可靠的面向连接地传输方法。数据无差错,无重复地发送,而且按发送地顺序进行接收。不论对单个数据报,还是对整个数据包,流式套接字都提供一种流式数据传输,流式套接字使用TCP协议。此外,在数据传输时,如果连接断开,应用程序会被通知。流式套接字内设流量控制,避免数据流超限;数据被看成字节流,无长度限制。

3.1.2.2  数据报套接字(DGRM)
数据报套接字提供一种不可靠的,非连接的数据包(Packet)通信方式。在这里,”不可靠”是指发送一个数据包不能获得担保,也不能保证数据包按照发送的顺序到达目的地。数据包以独立包形式被发送,不提供无错保证,数据可能丢失或重复,并且顺序混乱。在实现上,同一分组数据报可能不止一次的被发送。对于Socket的TCP/IP实现,数据报套接字使用用户数据报协议(UDP)。虽然在通常情况下,在同一台计算机或在轻负载的局域网所连接的两台计算机的进程之间进行通信时,可能不会出现数据包不被发送或没按照顺序到达及又重复发送的情况,但在编写应用程序时,应该注意检测意外发生的事件,应具备处理出现这些情况的能力。当然,如果为非常复杂的网络(如Internet)编写通信应用程序,就应该考虑到数据报套接字的不可靠性。如果我们的应用程序没有处理好这个问题,它就有可能崩溃。尽管如此,数据报套接字在发送数据包或者记录数据时仍然有用。另外,数据报套接字还提供向多个目的地发送广播数据包的能力。

3.1.2.3  原始套接字(RAW)
该接口允许对较低层协议,如IP,ICMP的直接访问。它通常用于检验新的协议实现或访问现有服务配置中的新设备。

3.1.3  Socket类中的常规函数调用
客户应用程序与服务器应用程序间的通信,通常由一个规定的事件序列来完成。
首先,客户端和服务器端都要创建一个套接字。接着,服务器调用bind()函数给套接字分配公认的端口(在开发应用程序时,这个公认的端口通常是指定的。例如本程序的端口就指定为7068)。这样,客户端和服务器端就使用同一个端口来表示服务器套接字。一旦服务器将公认的端口分配给了套接字,客户端和服务器端都能使用Send()和Receive()来发送和接收数据报直到完成传输。然后调用close()来关闭套接字。下面具体看从给定套接字的一个地址开始的每一步工作是怎样进行的。

3.1.3.1 创建套接字
系统调用socket()函数向应用程序提供套接字手段时的声明如下:
Public Socket(AddressFamily addressFamily,SocketType socketType,ProtocolType protocolType);
该函数有三个参数,其中参数addressFamily指定通信发生的区域,在DOS,Windows系统中支持InterNetwork,它指网际网区域。
参数socketType描述要建立套接字的类型。也就是指是流式套接字还是数据报套接字。
参数ProtocolType说明该套接字使用的协议,常用的是TCP和UDP两种协议。socket()函数根据这三个参数建立一个套接字,并将相应的资源分配给它,同时返回一个套接字类型。

3.1.3.2 服务器端地址绑定
当一个套接字用socket()创建以后,bind()将套接字地址(主机地址和端口)与所创建的套接字编号联系起来,即将名字赋予套接字。bind()声明如下:
Socket Bind(EndPoint localEP);
bind()函数只有一个参数EndPoint类型。它的原型是IPEndPoint (long IpAddress,int port);参数IpAddress是赋给套接字的本地地址。参数port指套接字监听的端口。
绑定地址之后,就可以开始监听(listen)并进入等待连接(accept)状态。

3.1.3.3 建立套接字连接
建立套接字连接的请求来自客户端,客户端用到的函数是connect(),服务器用到的函数是accept()。connect()函数的原型声明如下:
Socket Connect(IPEndPoint iep);
Connect()只有一个参数IPEndPoint,IPEndPoint的函数原型在之前已经已经介绍过,此处不再赘述。Accept()函数原型声明如下:
Socket Accept();
该函数没有参数,在做accept函数调用前要先调用listen() ,连接成功,该函数返回一个SOCKET类型的值。
Socket(),bind(),connect(),accept()这四个套接字系统调用可以完成一个完全的通信建立,包括协议,本地主机地址和端口,目的地址和端口。socket()指定协议元,他的用法与是否为客户机和服务器,是否面向连接无关,bind()指定本机地址和端口号,是面向连接的。服务器方必须调用bind()函数(当然,如果用TcpListener类,则另当别论);

3.1.3.4 数据传输
当连接建立以后,就可以开始传输数据了。通常调用Send()和Receive()函数。Send()函数原型声明如下:
int Send(byte[] buffer,int size,SocketFlags socketFlag);这是最常用的,另外还有七个重载方法,此处就不一一介绍了。
该函数共有三个参数,其中buffer指要发送的内容(已转为字节流)。字节流长度由size指定。socketFlag是传输控制方式,如是否发送带外数据等。函数返回发送的总字节数。若返回值为0,则说明发送失败。
Receive ()函数一般在Accept()之后被调用,当没有连接的时候,程序阻塞在Listen()函数处,一旦连接成功,则程序继续往下,至Receive()处阻塞,直到客户端有数据发送过来。其函数原型声明如下:
int Receive(byte[] buffer,int size,SocketFlags socketFlag);
参数的意义同Send()函数;

3.1.3.5 关闭套接字
Close()关闭套接字,并释放分配给该套接字的资源,其函数原型为:
void Close();
该函数不带参数,且没有返回值。

3.2 .NET中的Socket编程
.NET中对WinSock API函数进行了大量的封装,主要存在于命名空间System.Net和System.Net.Sockets中。因此在.NET中进行Socket编程变得非常的容易。首先,我们需要引进上面提到的两个命名空间。然后在服务端进行相应的编码:
public static Socket a_Socket=new Socket=new Socket
(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPAddress l_strIp=IPAddress.Parse(string a_strIp);
TcpListener listen=new TcpListener (l_strIp,7068); //对端口7068进行监听
listen.Start();
a_Socket=listen.AcceptSocket(); //接受连接
服务端的服务启动后,只要尚未检测到连接请求,就会一直阻塞在listen.Start()处。直至监听到请求,并完成连接。
客户端的编码则相对简单,只要创建套接字,并取得服务端的ip和相应的端口,即可进行连接,代码大致如下:
IPAddress myIP=IPAddress.Parse(ip);
IPEndPoint remoteEP=new IPEndPoint (myIP,port);
Socket c_Socket=new Socket(AddressFamily.InterNetwork,
SocketType.Stream,ProtocolType.Tcp);
c_Socket.Connect(remoteEP);

3.3 客户端实现
主要实现功能:
1)、通过命令控制,直接在被控端执行DOS命令。并返回执行结果。
2)、从被控端下载文件至本地。
3)、取得被控端屏幕,并进行控制。
4)、重启或关闭被控端计算机。
5)、查看被控端文件内容。

3.3.1 客户端界面设计
相对服务器端(被控端)的设计,客户端较为简单。客户端的设计选用了.NET中的Windows Applications框架。在窗口上添加一些控件。修改相应的编辑框属性。添加相应的成员变量。从图4可以清楚的看到,在未登录服务器之前,注销,直接控屏和发送按钮以及要发送的命令的窗口都是不可用的,同时,本软件设置了一个显示消息窗口,用来接收服务器端发回来的反馈消息。

3.3.2  连接远程主机
在本软件设计初期,我想到的不是通过指定要连接的计算机的IP地址进行远程的控制连接,而是由软件自动搜索,通过搜索后得到的计算机结果去连接要连接的那台计算机。但是后来想到,搜索后的结果不一定有想要连接的那台计算机,而且,自动搜索会具有一定的黑客性质。在通过远程网络控制通信时,先指定要登录的计算机的IP,有针对性的连接,这样安全性也好一点。
因此,在图4中的被控端信息栏里就有了IP地址的输入栏(由于服务端监听的端口是指定的,因此在客户端选择端口根本就没有意义)。登陆时。在IP地址栏填入被控端的IP地址,端口号(本程序的端口设置为7068),点击登陆,就可以了。

3.3.3 发送命令
系统通信协议定义:此程序的通信协议是自定义的。但是,我这边做得稍微简单了点,因为DOS命令本身,就为大部分人所熟悉。我直接用即可,没必要说自定义个命令,然后到服务端再去做相应的转换工作,实在多此一举。下面我只列出了几个用到的非DOS命令,但这些命令,并不是由用户敲进去的,而是程序运行过程中,内部用到的,对用户不透明的命令。
系统通信协议
src 直接控屏的时候,发给服务端的命令标识
download 文件下载的时候,发送的命令
close 通知服务端关闭套接字
点击发送按钮时,程序从命令输入框中取得命令的字符串(string类型),利用Send()函数来发送命令。返回的结果在信息显示窗口显示出来。而且,在服务器端,过滤了“src”、“close”和“download”三种命令(非一般的DOS命令),更有利于服务器对客户端发送的命令的执行。具体详细实现方法可以参阅附录的源代码。

3.3.4 直接控屏
控制屏幕是本程序最主要和最重要的功能模块,不管是服务器,还是客户端,在实现远程屏幕监视方面都比较麻烦和复杂。本程序的远程控制屏幕模块采用了通过服务器端抓取被控端的桌面和图形,并且还有捕获鼠标和键盘的相应函数,一同通过服务器和客户端的Socket连接,发送到控制端。在控制端,要把抓出来的图形和键盘鼠标等相应函数联系起来,再捕获控制端的鼠标键盘在被控端图形显示区域里的响应以及相应位置。在通过控制端的操作,通过函数回应,发回到被控端,映射到被控端的相应位置。在利用返回的鼠标键盘的函数操作,调用本地的鼠标键盘的函数操作,来实现对被控端的控制。
在实现控制屏幕功能模块中,专门建立了一个屏幕控制窗口类ScreenCtrl,其界面上放置了一个pictureBox控件,用于显示从服务端接收到的桌面图像。在窗体加载的事件里创建了新的线程,用来执行控屏操作,具体如下:
 private void ScreenCtrlLoad(object sender, EventArgs e)
 {
   try
   {
    CheckForIllegalCrossThreadCalls=false;
    Thread linkedForServerThread = new Thread(new ParameterizedThreadStart(LinkedForServer));
              //后台线程
    linkedForServerThread.IsBackground = true;
    linkedForServerThread.Start(_Socket);
   }
   catch (Exception er)
   {
    MessageBox.Show(this, er.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
   }
}
窗体加载完,并ShowDialog()之后,就会在pictureBox中显示接收到的第一张图片(之后循环接收后续图像数据并显示)。为了响应鼠标和键盘的操作,pictureBox实现了MouseDown、MouseUp、MouseMove、MouseWheel、MouseClick、MouseDoubleClick、KeyDown等七个事件。实现该模块的流程图如下所示:
有了以上的连接请求,再和服务器端的设计相结合,就可以实现对远程计算机屏幕的控制了。

3.3.5 帮助
帮助功能模块其实就是软件的使用说明。主要介绍软件的命令。

3.4 服务端实现
被控端程序是远程控制软件的主体。软件的具体功能都是在被控制端实现的,主控端只负责传送要执行的命令和显示返回的结果。而几乎所有的操作控制都是在被控端本地实现的。远程控制的被控端要求自动运行,同时还应该要具有一定的隐藏性,不容易被用户发现和关闭,当然,这要在Window任务管理器里看不到。故界面简单,并且自动改成和系统配置中的名称相近的名称。这样才不容易被用户发现。
由于服务端基本不涉及界面操作,而且在服务启动后,程序是要隐藏运行的,因此,其界面就可以做得相对简单些了。具体界面如下图所示:   
让程序运行时,在任务管理器中看不到,只要一句话就可以了,如下:
this.ShowInTaskbar=false;

3.4.1 进行监听、时刻准备连接
服务端Socket从一开始就一直保持监听状态,等待客户端的连接请求。

3.4.2 程序设置自动运行
远程控制软件要求被控端程序只手动运行一次,然后每次计算机启动时自动运行,而且,一般也要求隐藏运行,最好要求被控端的用户看不到控制端软件的运行,甚至用Ctrl+Alt+Del调出任务管理器也看不出来,这样,被控端就不能关闭运行的远程控制程序。
本软件是利用修改注册表的方法来实现程序的自动启动的。注册表保存系统的软、硬件及其他与系统配置有关的重要信息。在计算机的系统注册表中的子目录中有一个目录,该名称为:HKEY_LOCAL_MACHINE\Software\Microsoft\ Windows\CurrentVersion\Run,只要把要求自动运行的程序添加到该目录的一个子项里,就可以实现该程序的自动运行了,而且为了迷惑被控端的用户,可以将程序拷贝到系统目录下,并且改一个和系统目录下相近的名字,如internt.exe具体操作如下:
设置注册表的相关路径:
在C#中进行注册表操作,需要引入命名空间Microsoft.Win32。其中提供了两个类RegistryKey和Registry。
string keyValue="SOFTWARE\\Microsoft\\Windows\\CurrentVersion
\\Run";
SOFTWARE\Microsoft\Windows\CurrentVersion\Run,是所有软件自动运行的统一键值。修改它,就可以注册自动运行了。然后再获得系统目录: GetSystemDirectory(SysPath,size);并且把文件拷贝到系统目录下,改名为internt.exe。这样就算用户发现了这个文件,也会误以为是系统文件而不敢乱删除。具体实现如下:
[DllImport("kernel32")]
public static extern void GetSystemDirectory(StringBuilder SysDir,int count);
const int nChars = 128;
StringBuilder Buff = new StringBuilder(nChars);
GetSystemDirectory(Buff,nChars);   
string sysDirectory=Buff.ToString()+"\\internt.exe";
File.Copy(Application.ExecutablePath,sysDirectory);
然后注册为自动运行:注册自动运行要先打开注册表
RegistryKey regKey=Registry.LocalMachine.OpenSubKey(keyValue,
true);
然后将要自动运行的程序写入注册表内,如下:
regKey.SetValue("remoteCtrl",sysDirectory);
再添加一下出错处理函数就可以完成完整的注册自动运行的函数了;

3.4.3 查看文件内容
一般是指*.txt文件,用type命令即可。如:type D:\file.txt。
若是其他格式的文件,则可以下载下来之后再看。

3.4.5 文件下载
当接收到的客户端命令满足条件recvStr.Substring(0,8)==
"DownLoad"时,服务器端取得客户端传过来的文件路径,并创建文件流,读文件至一个字节数组,然后发送至客户端即可。

3.4.8 远程屏幕抓取的实现
在远程控制的实践中,控制端用户要想知道被控端的用户在干什么,一般有两种方法,一种方式是记录被控端的键盘和鼠标事件,形成一个文本文件,然后把文件发到控制端。控制端用户通过查看文件的方式了解被控端的用户打开了哪些程序,敲哪些键。这样,虽然知道了用户的一些操作,但是不直观,而且查阅起来也不方便。另外,要想让程序在用户不知道的情况下去监视键盘,这个技术是非常复杂的,至少现在的我还做不到。这时,就要用到另一种方式。即在被控端抓取当前的屏幕,形成位图文件,然后把该文件发送到控制端计算机并显示出来,实现远程屏幕抓取。取得当前屏幕图像的方法如下:
Image deskImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height,PixelFormat.Format24bppRgb);
Graphics deskG = Graphics.FromImage(deskImage);
deskG.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.PrimaryScreen.Bounds.Size);
Rectangle targRect = new Rectangle(0, 0, 640, 480);
Image baseImage = new Bitmap(640,480,PixelFormat.Format24bppRgb);
Graphics baseG = Graphics.FromImage(baseImage);
baseG.DrawImage(deskImage, targRect, new Rectangle(0, 0,
deskImage.Width, deskImage.Height), GraphicsUnit.Pixel);
之后将baseImage转换为字节数组,传至客户端即可。再与鼠标键盘事件控制相结合就可以实现直接屏幕控制了! 客户端主要是负责向服务端发出获取服务端屏幕图像数据的请求,把从服务端发送来的屏幕图像在本地实时地显示出来;而服务端主要是负责响应客户端的请求并抓取与发送屏幕图像。
具体实现的流程图如下:
至此,鼠标、键盘、屏控等模块就介绍完了,本系统的实现也到此为止。

四、总结
结  论
在论文写作中涉及到的技术,我都尽量列出了函数原型,以帮助理解和应用。通过对此程序的设计、编码,使我加深了对所学课程《计算机网络》的了解,同时也熟悉了网络编程的许多方面,加深了对系统结构等知识的了解。熟悉了VC#的网络编程以及C++程序、系统API等与.NET的融合。
另外,本程序在直接控屏功能实现上还有一点问题,由于不管是被控端还是控制端发送和接受的都是位图,所以要求的数据量就比较大。导致程序在运行一段时间后会变得越来越慢,直至无法响应。而且,在控制端对被控端的有些操作还不能完全实现,有待于进一步完善。尤其是在重启和关机方面,由于程序运行于用户模式,所以有些涉及权限的操作,都未必能如我们所想的运行下去。因此,取得进程调用权限显得尤为重要。而这一点,我虽然尝试去做了,但是实现的并不是很完全,有待进一步完善。

参考文献:
[1] C++程序设计教程   H.M.Deitel、P.J.Deitel【美】 著 施平安 译  清华大学出版社
[2] 深入浅出MFC  侯俊杰【台】 著   华中理工大学出版社
[3] 远程控制编程技术  张友生 编著  电子工业出版社
[4] 王达.计算机网络远程控制 [M].北京:清华大学出版社,2003
[5] 谢希仁.计算机网络[M].大连:大连理工大学出版社,2000
[6] 刘小辉.网络管理[M].北京:人民邮电出版社,2002
[7] 严蔚敏等编.数据结构[M].北京:清华大学出版社,1997
[8] 潘爱民 译  深入解析windows操作系统  北京:电子工业出版社 2007
[9] 齐立波 译  C#入门经典  北京 清华大学出版社  2009
[10] 李铭 译 C#高级编程(第六版) 北京 清华大学出版社 2008
[11] Windows程序设计 北京大学出版社

致   谢
本文在写作过程中,接受了外部多方面的帮助,有来自同学的资料援助,有指导老师在宏观上的点拨,也有朋友们在编码方面的提点,以及其他很多...当然最多的帮助还是来自网络。在此,对给予帮助的诸位良师益友,诚心的表示感谢,谢谢各位!