基于JAVA实时监控远程控制系统设计和实现毕业论文.doc_第1页
基于JAVA实时监控远程控制系统设计和实现毕业论文.doc_第2页
基于JAVA实时监控远程控制系统设计和实现毕业论文.doc_第3页
基于JAVA实时监控远程控制系统设计和实现毕业论文.doc_第4页
基于JAVA实时监控远程控制系统设计和实现毕业论文.doc_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于JAVA实时监控远程控制系统设计和实现毕业论文目 录引言 31 课题描述 51.1 任务内容 51.2 应完成内容 52 系统分析62.1 系统功能分析62.2 系统软件模型63 相关技术 73.1 Socket的基本概念 73.1.1 Socket 引入73.1.2 Socket的类型 73.2 基本套接字函数调用 83.2.1创建套接字83.2.2 指定本机地址83.2.3 建立套接字连接83.2.4 监听连接 9 3.2.5 数据传输 93.2.6 关闭套接字103.3 Windows系统的Socket编程103.3.1 使用WinSock API103.3.2 使用数据报套接字103.3.3 使用流式套接字113.4 Windows的消息系统 144 C/S模式远程控制程序设计实现 174.1主要实现功能174.2 客户端(监控端)设计实现184.2.1添加主机194.2.2发送消息 204.2.3监视屏幕 204.2.4帮助 214.2.5 注册21 4.3 服务器端(被监控端)设计实现234.3.1准备接受连接 244.3.2自动运行和隐藏 254.3.3 文件管理的实现2 列文件目录清单2 查看文件内容2 “文件传输”程序实现294.3.4 系统信息的获取及修改 294.3.5 远程重启,关闭计算机的实现294.3.6 键盘和鼠标的控制 324.3.7 远程屏幕抓取的实现 374.3.8 其他功能模块的实现 395 总结与展望 39谢辞39参考文献 39附录 4058引言:网络在计算机世界里,越来越发挥着举足轻重的作用,很多单位、部门都建立了自己的内部网。对于网络管理人员来说,在整个网络运行期间,希望能够实时的监控联网计算机的运行状态和进行一些相关操作;希望能够传输文件;希望能够防止病毒的蔓延、非法程序的拷贝、杜绝某些用户的越权或非法操作等。为此,希望编写一个适合于自己所在局域网的通讯程序。在此,本人使用VC 6.0开发了一套能在局域网内的每台计算机进行实时监控的网络系统。这也就是所谓的远程控制软件。那什么是远程控制?远程控制是在网络上由一台电脑(主控端Remote/客户端)远距离去控制另一台电脑(被控端Host/服务器端)的技术,这里的远程不是字面意思的远距离,一般指通过网络控制远端电脑,不过,大多数时候我们所说的远程控制往往指在局域网中的远程控制而言。当操作者使用主控端电脑控制被控端电脑时,就如同坐在被控端电脑的屏幕前一样,可以启动被控端电脑的应用程序,可以使用被控端电脑的文件资料,甚至可以利用被控端电脑的外部打印设备(打印机)和通信设备(调制解调器或者专线等)来进行打印和访问互联网,就像你利用遥控器遥控电视的音量、变换频道或者开关电视机一样。不过,有一个概念需要明确,那就是主控端电脑只是将键盘和鼠标的指令传送给远程电脑,同时将被控端电脑的屏幕画面通过通信线路回传过来。也就是说,我们控制被控端电脑进行操作似乎是在眼前的电脑上进行的,实质是在远程的电脑中实现的,不论打开文件,还是上网浏览、下载等都是存储在远程的被控端电脑中的。电脑中的远程控制技术,始于DOS时代,只不过当时由于技术上没有什么大的变化,网络不发达,市场没有更高的要求,所以远程控制技术没有引起更多人的注意。但是,随着网络的高度发展,电脑的管理及技术支持的需要,远程操作及控制技术越来越引起人们的关注。远程控制一般支持下面的这些网络方式:LAN、WAN、拨号方式、互联网方式。此外,有的远程控制软件还支持通过串口、并口、红外端口来对远程机进行控制(不过,这里说的远程电脑,只能是有限距离范围内的电脑了)。传统的远程控制软件一般使用NETBEUI、NETBIOS、IPX/SPX、TCP/IP等协议来实现远程控制,不过,随着网络技术的发展,目前很多远程控制软件提供通过Web页面以JAVA技术来控制远程电脑,这样可以实现不同操作系统下的远程控制,例如数技通科技有限公司在去年就推出了全球第一套基于中文JAVA的跨平台远程控制软件易控。远程控制软件一般分两个部分:一部分是客户端程序Client,另一部分是服务器端程序Server,在使用前需要将客户端程序安装到主控端电脑上,将服务器端程序安装到被控端电脑上。它的控制的过程一般是先在主控端电脑上执行客户端程序,像一个普通的客户一样向被控端电脑中的服务器端程序发出信号,建立一个特殊的远程服务,然后通过这个远程服务,使用各种远程控制功能发送远程控制命令,控制被控端电脑中的各种应用程序运行,我们称这种远程控制方式为基于远程服务的远程控制。通过远程控制软件,我们可以进行很多方面的远程控制,包括获取目标电脑屏幕图像、窗口及进程列表;记录并提取远端键盘事件(击键序列,即监视远端键盘输入的内容);可以打开、关闭目标电脑的任意目录并实现资源共享;提取拨号网络及普通程序的密码;激活、中止远端程序进程;管理远端电脑的文件和文件夹;关闭或者重新启动远端电脑中的操作系统;修改Windows注册表;通过远端电脑上、下载文件和捕获音频、视频信号等。前面所讲的是一台电脑对一台电脑的情况,其实,基于远程服务的远程控制最适合的模式是一对多,即利用远程控制软件,我们可以使用一台电脑控制多台电脑,这就不必为办公室的每一台电脑都安装一个调制解调器,而只需要利用办公室局域网的优势就可以轻松实现远程多点控制了。在进行一台电脑对多台远端电脑进行控制时,远程控制软件似乎更像一个局域网的网络管理员,而提供远程控制的远程终端服务就像极了办公室局域网的延伸。这种一对多的连接方式在节省了调制解调器的同时,还使得网络的接入更加安全可靠,网络管理员也更易于管理局域网上的每一台电脑。远程控制具有一下优点:便于用户能够在任何地方通过网络及时,快速的访问,控制自己的主机。特别是对于网络管理员,技术服务人员来说,远程控制提供了一个便捷,高效的手段。 当然,远程控制软件是一把双刃剑,有优点就会有缺点,它存在比较严重的安全隐患。一方面给用户和网络管理员工作带了很大的方便,另一方面也给一些居心不良者留下后门。形成很多木马程序。这就需要对软件在设计方面做一些安全考虑。本软件就是基于此而设计开发的,能实现以下的基本的远程功能:1),查看被控制端的文件目录清单;2),查看被控制端的文件内容;3),拷贝被控制端的文件到控制端;4),强迫被控制端重新启动或关机;5),修改被控制端的系统配置文件;6),直接执行任何可执行命令,打开应用程序;7),锁住(解锁)被控制端的屏幕,键盘和鼠标;8),控制被控制端的屏幕,在本地直接操作被控制端计算机;9),隐藏共享被控制端的硬盘;10),同时可以做到被控端的服务器自动运行及隐藏等功能;而且做了一些必要的安全性考虑。1 课题描述:1.1 任务内容 基于Windows的远程控制软件开发毕业设计的主要任务是要求做出从系统角度计的远程控制模式,并制作相应实用软件。采用服务器(Server),客户端(Client)模式,使用Socket编程的基本原理及Windows的消息系统。实现基本的远程控制要求,界面新颖友好。用VC开发!要求: 1)远程控制模式架构,如基于主从模式; 2)远程控制功能实现,如开关机,远程监视; 3)远程控制安全考虑; 4)远程控制实现平台与技巧; 5)远程控制软件实现,要求至少能在两台电脑上正常运行; 6)界面新颖友好。1.2 应完成内容1),查看被控制端的文件目录清单;2),查看被控制端的文件内容;3),拷贝被控制端的文件到控制端;4),强迫被控制端重新启动或关机;5),修改被控制端的系统配置文件;6),直接执行任何可执行命令,打开应用程序;7),锁住(解锁)被控制端的屏幕,键盘和鼠标;8),控制被控制端的屏幕,在本地直接操作被控制端计算机;9),隐藏共享被控制端的硬盘;10),同时可以做到被控端的服务器自动运行及隐藏等功能;11),补充:做不好的话,会带来严重的安全隐患。会给一些居心不良的人留下后面。所以要同时做好相关的安全性考虑。2 系统分析2.1 系统功能分析本程序是由客户端和服务器端两部分组成的。而且需要客户端和服务器端同时运行相应的程序来实现的。本软件要实现的基本功能可以简化如下: 第一步,服务器端运行相应的远程控制软件服务器程序,使服务器端的某个端口处于监听状态(本软件端口设置为4069)。这样服务器端计算机就时刻处于监听远程计算机连接请求的状态。 第二步,当服务器端程序运行后,客户端在本地计算机中运行相应程序的客户端程序,运行这个客户端程序时,会指定一个要连接的服务器的IP地址和端口,(本软件初始化的服务器地址是,端口:4069),程序运行后,点击连接就会向所有的网络搜索指定的计算机了。 第三步,搜索到所指定的计算机后,客户端计算机就向服务器端指定的端口发送连接请求(本软件使用TCP连接),如果服务器端计算机同一端口处于监听状态,则服务器端接收客户端的连接请求,并根据设定的值向客户端发送接受请求确认信号,并同时向客户端发出登录成功信息确认对话框。 第四步,客户端输入登录信息并确认后,就会向服务器端发送,服务器端接收到客户端发来的用户信息后,就开始对客户端所输入的客户进行合法性确认,如果不符合登录条件,则拒绝用户的连接。 第五步,如果服务器端确认客户端所输入的用户符合服务器端计算机的条件,则服务器端允许客户端进行进一步的连接,这样,整个软件的连接过程就完成了。2.2系统软件模型 在本软件设计中,采用典型的C/S结构,由客户端与服务端两部分构成。客户/服务器模式的最显著特点是非对等作用,即客户相对于服务器处于不平等的地位,服务端提供服务,客户端提供请求。结构如图2.1所示: Server Client应用程序操作系统网络接口应用程序操作系统网络接口 网络 服务响应 服务请求 图2.1 在设计客户端和服务器时,由于功能需求不同,我设计的客户端界面简单,面向对象,并且由相应的帮助文件,易于操作。而服务器端主要实现控制功能实现。而且不能让用户强行关闭,界面就简单,而且要做到隐藏。其他详细的功能模块描述将在第四章具体功能模块实现中给予描述。以下两章详细介绍了本程序的实现的基础和过程:3 相关技术客户/服务器技术是当今比较流行与具有发展的技术之一。以之构成的客户、服务器应用系统具有系统结构优化、资源利用率高、整体运算速度快的优点,因而得到了广泛的应用。在WINDOWS应用程序中,处理实时通讯最常用到的还是MICROSOFT公司提供的WinSock控件。3. 1 WinSock基本概念网络客户/服务器模式的原理是一台主机提供服务(服务器),另一台主机接受服务(客户机)。作为服务器的主机打开一个端口并进行监听, 如果有客户机向服务器的这一端口提出连接请求, 服务器上的相应程序就会自动运行,来应答客户机的请求。而WinSock的正确使用,给设计者带来了极大的方便,使得各种应用程序能够在Windows环境下顺利进行各种网络通讯。3.1.1 Socket 引入20世纪80年代初,美国政府的高级研究工程机构(ARPA)给加利福尼亚大学Berkeley分校提供资金,让他们在UNIX操作系统下实现TCP/IP协议。在这个项目中,研究人员为TCP/IP网络通信开发了一个应用程序接口(API)。这个API就称为Socket接口。今天,Socket接口是TCP/IP网络最通用的API,也是在Internet上进行应用开发最为通用的API。 实际上,Socket在计算机中提供了一个通信端口(套接口)。通过这个端口,一台计算机可以与任何一台具有Socket接口的计算机通信。通信的基础是套接口。一个套接口是通信的一端,在这一端上可以找到与其对应的一个名字。一个正在被使用的套接口都有它的类型和与其相关的进程,套接口存在于通信域中。一个讨套接口通常和同一个域中的套接口交换数据(数据交换也可以穿越域的界限,单这时一定要执行某种解释程序)。应用程序在网络上传输,接收的信息都通过这个套接口来实现。在应用开发种就像使用文件句柄一样,可以对Socket句柄进行读写操作。 开始使用套接字编程之前,首先必须建立这些概念:网间进程通讯,服务方式,客户机/服务器模式。 进程通信的概念最初来源与单机系统。由于每个进程都在自己的地址范围内运行,为保证量相互通信的进程之间既互不干涉又能协调一致工作,操作系统为进程通信提供了相应设施,如UNIX BSD中的管道(Pipe)、命名管道(Named Pipe)和软中断信号(Signal)、UNIX System V的消息(Message)、共享存储区(Shared Memory)和信号量(Semaphore)等,但都仅限于用在本机进程之间的通信。网间进程通信要解决的是不同计算机进程间的相互通信问题(可把同机进程通信看成是其中的一个特例)。为此,首先要解决的是网间进程标识问题,同一计算机上,不同进程可以用进程号(Process ID)作为唯一标识,但在网络环境下,各个计算机独立分配的进程号不能唯一的标识该进程。例如,计算机甲赋予某进程号48,在乙计算机中也可以存在48号进程,因此,“48号进程”这句话就没有意义了。其次,操作系统支持的网络协议众多,不同的协议的工作方式不同,地址格式也不一样,因此,网间进程通信还要解决多重协议的识别问题。 在网络分层结构中,各层之间是严格单向依赖的,各个层次的分工和协作集中体现在相邻层之间的界面上。“服务”是描述相邻层之间关系的抽象概念,即网络中各层向紧邻上层提供的一组操作。下层是服务提供者,上层是请求服务的用户。服务的表现形式是原语(Primitive),如系统调用或库函数等。系统调用是操作系统内核向网络应用程序或高层协议提供的服务原语。在国际标准化组织(ISO)的术语中,网络层及其以下各层又称为通信子网,只是提供点到点的通信,没有程序或进程的概念。而传输层实现的是“端到端”通信,引进网间进程通信概念,同时也要解决差错控制、流量控制、数据排序(报文排序)及连接管理等问题。为此提供不同的服务方式:面向连接(虚电路)的服务或无连接的服务。面向连接服务是电话系统服务模式的抽象,即每一次完整的数据传输都要经过建立连接,使用连接及终止连接的过程。在数据传输过程中,各数据分组不携带目的地址,而使用连接号(Connect ID)。本质上,连接是一个管道,收发数据不但顺序一致,而且内容相同。其中TCP协议就提供面向连接的虚电路。无连接的服务是邮政系统服务的抽象,每个分组都携带完整的目的地址,各分组在系统中独立传送。无连接服务不能保证分组的先后顺序,不进行分组出错的恢复与重传,不保证传输的可靠性。提供无连接的数据报服务的常用协议是UDP协议。 在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式就是客户机/服务器模式(Client/Server)。即客户向服务发出服务请求,服务接收到请求后,提供相应的服务。客户机/服务器模式的建立基于以下两点:首先,建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用;其次,网间进程通信完全是异步的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为两者的数据交换提供同步,这就是基于客户机/服务器式的TCP/IP。3.1.2 Socket的类型TCP/IP的Socket提供下列三种类型套接字。1, 流式套接字(SOCKSTREAM)如果我们想让发送出去的数据按顺序无重复地到达目的地,那么就需要使用流式套接字。流式套接字提供一种可靠的面向连接地传输方法。数据无差错,无重复地发送,而且按发送地顺序进行接收。不过对单个地数据报,还是对整个数据包,流式套接字都提供一种流式数据传输,流式套系在使用TCP。此外,在数据传输时,如果连接断开,应用程序会被通知。流式套接字内设流量控制,避免数据流超限;数据被看成字节流,无长度限制。FTP使用这种。2,数据报套接字(SOCKE_DGRM)数据报套接字提供一种不可靠的,非连接的数据包(Packet)通信方式。在这里,”不可靠”是指发送一个数据包不能获得担保,也不能保证数据包按照发送的顺序到达目的地。数据包以独立包形式被发送,不提供无错保证,数据可能丢失或重复,并且顺序混乱。在实现上,同一分组数据报可能不止一次的被发送。对于WinSock的TCP/IP实现,数据报套接字使用用户数据报协议(UDP)。虽然在通常情况下,在同一台计算机傻瓜或在轻负载的局域网所连接的两台计算机的进程之间进行通信时,可能不会出现数据包不被发送或没按照顺序到达及又重复发送的情况,但在编写应用程序时,应该注意检测意外发生的事件,应具备处理出现这些情况的能力。当然,如果为非常复杂的网络(如Internet)编写通信应用程序,就应该考虑到数据报套接字的不可靠性。如果我们的应用程序没有处理好这个问题,它就有可能崩溃。尽管如此,数据报套接字在发送数据包或者记录形数据时仍然有用。另外,数据报套接字还提供向多个目的地发送广播数据包的能力。3 原始套接字(SOCKE_RAW)该接口允许对较低层协议,如IP,ICMP的直接访问。它通常用于检验新的协议实现或访问现有服务配置中的新设备3.2 基本套接字函数调用 大多数的数据报套接字应用程序都使用一个规定的事件序列来完成客户应用程序与服务器应用程序间的通信,如图3.1所示: Client Server socket() socket() bind() sendto() recvfrom() recvfrom() sendto() . . closesocket(); closesocket() 图3.1 首先,客户端和服务器端都要创建一个数据报套接字。接着,服务器调用bind()函数给套接字分配工人的端口(在开发应用程序时,这个公认的端口通常时指定的。例如本程序的端口就指定为4069)。这样,客户端和服务器端就使用同一个端口来表示服务器套接字。一旦服务器将公认的端口分配给了套接字,客户端和服务器端都能使用sendto()和recvfrom()来发送和接收数据报直到完成传输。然后调用closesocket()来关闭套接字。下面具体看从给定套接字的一个地址开始的每一步工作时怎样进行的。3.2.1创建套接字系统调用socket()函数向应用程序提供套接字手段时的声明如下:SOCKET PASCAL FAR socket(int af, int type, int protocol);该函数有三个参数,其中参数af指定通信发生的区域,在DOS,Windows系统中支持AF_INET,它时网际网区域。 参数type描述要建立套接字的类型。也就是指是流式套接字还是数据报套接字。 参数protocol说明该套接字使用的协议,如果该参数为0,则表示使用默认的连接模式。 Socket()函数根据这三个参数建立一个套接字,并将相应的资源分配给它,同时返回一个整形套接字句柄。3.2.2 指定本机地址当一个套接字用socket()创建以后,bind()将套接字地址(主机地址和端口)与所创建的套接字编号联系起来,即将名字赋予套接字。bind()声明如下: int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR *name, int namelen);bind()函数共有三个参数,其中参数s是由socket()函数调用返回的并且未连接的套接字句柄。参数name是赋给套接字s的本地地址。参数namelen指参数name的长度,调用成功,返回0;否则返回SOCKET_ERROR。3.2.3 建立套接字连接 建立套接字是要用connect()与accept()。connect()函数的原型声明如下: int PASCAL FAR connect (SOCKET s,const struct sockaddr FAR *name,int namelen); Connect()共有三个参数,其中s指要建立连接的本届套接字句柄。参数name指对方套接字地址结构的指针,对方套接字地址长度由参数namelen说明。如果调有成功,返回0;否则返回SOCKET_ERROR。Accept()函数原型声明如下: SOCKETPASCAL FAR accept(SOCKET s, struct sockaddr FAR *addr,int FAR*addrlen);该函数也由三个参数,其中参数s为本地套接字句柄,在做accept函数调用的参数前要先调用listen(),参数addr是指向客户方套接字地址结构的指针,用来接收连接实体的地址。addr的确切格式由套接字创建时建立的地址簇决定。参数addrlen为客户方套接字地址的长度。如果调用成功,accept()函数返回一个SOCKET类型的值。否则返回INVALID_SOCKET。Socket(),bind(),connect(),accept()这四个套接字系统调用可以晚上一个完全的通信建立,包括协议,本地主机地址和端口,目的地址和端口。socket()指定协议元,他的用法与是否为客户机和服务器,是否面向连接无关,bind()指定本机地址和端口号,时面向连接的。在服务器方必须调用bind()函数;3.2.4 监听连接建立连接以后,服务器端要调用listen()函数,表明愿意接收连接,listen()要在accept()之前调用,原函数声明如下:int PASCAL FAR listen(SOCKET s,int backlog);该函数有两个参数,参数s标志一个本地已建立单尚未连接的套接字句柄,服务器愿意从它上面接收请求。参数backlog表示请求连接队列的最大长度,用于限制排队的请求个数,目前最大值为5。如果调用成功,listen()函数返回0;否则返回SOCKET_ERROR。3.2.5 数据传输当连接建立以后,就可以传输数据了,通常调用send()和recv()函数。send()函数原型声明如下: int PASCAL FAR send(SOCKET s,const char FAR *buf,int len,int flags);共有四个参数,其中s为已经连接的本地套接字句柄。buf指向存有发送数据的缓冲区指针,长度有len指定。flags智利队传输控制方式,如是否发送带外数据等。如果调用成功,返回总发送的字节数;否则,返回SOCKET_ERROR。Recv()函数调用用于在参数s指定的已经连接的数据报或流套接字上接收输入数据,原型声明如下: Int PASCAL FAR recv(SOCKET s ,char FAR *buf, int len,int flags);参数的意义同send();3.2.6 关闭套接字closesocket()关闭套接字s并释放分配给该套接字的资源,cosesocket()函数原型声明如下:BOOLPASCAL FAR close socket(SOCKET s);该函数只有一个参数s,指待关闭的套接字句柄。如果调用成功,返回0,否则返回SOCKET_ERROR。3.3 Windows系统的Socket编程 3.3.1 使用WinSock APIWinSock API在使用之前必须经过初始化。可以使用WSAStartup()函数来完成。其声明如下:Int WSAStarup(WORD wVersionRequested,LPWSADATA lpWSAData);该函数有两个参数,第一个参数是一个WORD(双字节)类型数值,他指要使用的WinSock规范的最高版本。其中主版本在低位字节,副版本号在高位字节。第二个参数是指向WSADATA结构的指针。该结构里有成员 wVersion规定WinSock的版本号,如果返回的wVersion成员中的版本号不能被应用程序所接受,我们就应该调用WSACleanup()并且退出应用程序。声明完套接字,接下来就可以用socket()函数创建一个套接字,声明如下:SOCKET PASCAL FAR socket(int af,int type,int protocol);其中af指这个套接字要使用的Internet地址。参数type指所创建的套接字的类别。protocol指套接字使用的协议,如果为0,就自动选择一个合适的协议。在WinSock1.1中,socket()采用如下调用:SOCKET myUDPSock =socket(AF_INET,SOCKET_DGRAM,IPPROTO_UDP)流式套接字:SOCKET myTOPSock=socket(AF_INET,SOCKET_DGRAM,IPPROTO_TOP)3.3.2 使用数据报套接字在使用数据报套接字时,首先,要调用bind()函数,声明如下: int PASCAL FAR bind (SOCKET s,const struct sockaddr FAR *addr,int namelen);其中s指要绑定的套接字句柄,addr时一个地址结果sockaddr_in,用来指定一个IP地址,结构如下:Struct sockaddr_in Short sin_family;(AF_INET)U_short sin_port;(端口) Struct in_addr sin_addr,;(地址) Char sin_aero8;(填充数)namelen 是指参数addr的长度。一旦在服务器端创建了一个套接字,并且赋给了特定的地址和端口,就可以随时接收来自客户端赌数据,我用了recvfrom()函数来实现的。 int recvfrom(SOCKET s,char FAR *buf, int len,int flags,struct sockaddr FAR *from,int FAR *fromlen );参数flags可以指定为MSG_PEEK,可以取出数据填入缓冲去,但仍会吧数据报留在输入队列。后面的两个参数用来返回发送数据报的套接字地址,然后就可以使用这个地址向发送者发回一个答复。如果数据报读入成功,则返回接收的字节数,否则返回SOCKET_REEOR。发送数据可以用sendto()函数实现,原型为: int sendto(SOCKET s,const char FAR *buf ,int len,int flags,const struct sockaddr FAR *to ,int to len)。参数意义与recvfrom()类似。3.3.3 使用流式套接字由于流式套接字使用的是基于连接的协议,所以,它要先建立连接,然后才能读数据, 和数据报套接字一样,流式套接字也由socket()函数来创建,而且,用时必须用bind()函数为他分配一个地址,在创建一个套接字时,使用流式套接字与数据报套接字唯一不同的是,socket()调用传递的是SOCK_STREAM,而不是SOCK_DGRAM。 当已经建立了套接字,并赋给它一个地址后,需要移植方法建立和客户端的连接,为了做到这一点,要使用监听连接。我使用了listen()函数,声明如下: int listen(SOCKET s,int backlog)参数Backlog告诉WinSock应用程序能接收多少个请求。 一旦套接字设置成监听,实际的连接要accept()函数来完成。函数accept()声明如下: SOCKET accept(SOCKET s,struct sockaddr FAR *addr,int FAR *addrlen); 与bind()和recvfrom()函数一样使用了sock_addr结构。如果连接成功的接受,accept()函数返回一个新的套接字句柄。如果出现错误,则返回INVALID_SOCKET,这时,可以调用WSAGetLastError()来得到更高关于错误的细节。原来的套系在将继续监听新的连接请求,新的请求可能会通过accept()函数的再一次调用而获得。 为了让服务器接受请求,必须先发送请求,客户端程序通过connect()函数来做这一点的,原型声明如下: int connect(SOCKET s,const struct sockaddr FAR *name,int namelen);参数sockaddr和namelen用来指定要连接的套系在的地址和端口。传给connect()函数的sockaddr结构和给服务器bind()函数的sockaddr结构是一样的。一旦客户端和服务器端建立了连接,就可以通过send()函数调用来发送数据了int send(SOCKET s,const char FAR *buf,int len,int flags);参数buf和len分别指向将有发送的数据的指针和长度。参数flags参数可以指定为MSG_DONTROUTE,告诉WinSock在发送数据时,不要使用循环消息。为了从流式套接字接收数据,可以使用recv()函数:int recv (SOCKET s,char FAR *buf,int leg,int falgs);参数flags可设置成MS-OOB,用来接收带外数据,或设置成MSG-PEEK用来向缓冲区填入接收到的数据。对于套接字来说,如果数据按照输入的队列接收过来的,recv()函数返回读入数据的字节数,否则,recv()将返回SOCKET_ERROR,并且WSAGetLastError()给出具体的错误。在默认的状态下,当套接字由socket()函数创建后,它被设置为对I/O操作的阻塞状态。 就要用到WSAAsyncSelect()函数。它预先在特定的时间发生时,指定一个送往应用程序的Windows消息。声明如下: intWSAAsyncSelect(SOCKET s,HWND hWnd,unsigned int wMsg long lEvent);参数hWnd指定将要发送消息的窗口句柄,这个消息时由参数wMsg指定的。通常wMsg指定一个用户定义的消息WM_USER+n参数lEvent指定让WinSock发送消息的事件,这个值由以下状态通过操作符(|)结合而来:FD_READ 数据正等待被读入FD_WRITE 套接字正准备写数据FD_OOB 带外数据正等待被读入。FD_ACCEPT 一个新来的连接正等待被接收。FD_CONNECT 套接字连接已经完成FD_CLOSE 套接字连接已经关闭。当完成一个套系在操作后,就要用closesocket()函数将它关闭。3.4 windows的消息系统 Windows 程序时基于一种事件驱动的编程模式,这就意味着应用程序所要做的大部分工作时随着Windows消息的变化而进行的。在本程序的实现过程中,涉及大量的系统消息处理和自定义消息的处理。因此,用到如何使用处理C+类的消息。3.4.1 消息的种类 应用程序所要做的每项工作几乎都是基于处理Windows消息的,这些消息以三种基本形式出现:常用的Windows、控件通知和命令。 Windows消息的ID通常加上前缀WM_,例如WM_QUIT。这些前缀为WM_的消息代表发生在应用程序中的窗口和视图处理消息(MFC为这些消息中的绝大部分提供了默认的操作)。 控件消息是由子窗口传向主窗口的WM_COMMAND消息。例如,只要编辑控件的当前内容被改变,它就会传递一个EN_CHANGE消息到主窗口(通常是对话框)。Windows消息控件通知通常由窗口对象来处理,即由类CWnd所派生的对象处理。 命令是由菜单、按钮(包括工具条)和快捷键传递来的WM_COMMAND消息。很多类可以处理命令消息,其中包括文档、文档模板、窗口、视图和应用程序及本身。 3.4.2 MFC中的消息处理 MFC为窗口下的消息处理提供了一种框架,使其使用起来比传统的Windows程序下做控件的消息处理的swithc case语句和ifelse语句更为简单。这是由于从CcomTarge派生的类能够拥有自己的消息映射。MFC用用户类的消息映射来决定怎样处理已经给定的消息。使我们能最大限度的利用C+语言的优点将我们的类进行功能性封装,这样,由这些类所创建的其他类就不用再次重复操作。 MFC为了进一步扩展重复使用性,它为大多数Windows应用程序,甚至范围更广的命令提供了默认操作。大多数有默认操作的命令同时也被包含在由AppWizard产生的默认菜单中。由AppWizard创建的菜单的标准命令消息在AFXRES.H中定义,例如,File|New菜单项产生一个有ID号为ID_FILE_NEW消息。其他的标准命令也有同样的命名规则,这个规则就是ID_+菜单名+命令名。如果想执行这些标准操作之一,可以从应用程序中的任何一处发送一则预定义号的命令消息,这一消息就能被MFC进行默认处理。当然,也可以对这些命令实现自己的处理。 3.4.3 用ClassWizard进行消息处理 对于绝大多数的消息处理任务来说,ClassWizard能提供极大的帮助。ClassWizard通过使用其中的消息映射项,能将消息映射成各种类所对应的处理程序。在程序设计阶段,可以使用View菜单或用Ctrl+W来启动ClassWizard。选择消息映射键后,将出现一个如图3.2的对话框。 图3.2 如果在工作区中有多个任务,首先需要在Project项中选择合适的入口,然后在类名项中选择一个由CCmdTarge所创建的类。这样将给我们提供一个对象ID列表,这些对象所接收到的消息以及在成员函数中已经实现了的成员函数表。 “Project”项指项目名称列表。“Class name”项指类名列表。 “Object IDs”项出现的对象有三种不同的类型:在“Class name”中列出的类,菜单项对象以及其他在“Class name”中所选的类传递消息的控件。 当从“Object IDs”项中选择类名时,会在“Messages”项中列出选中项所能接收的所有Windows消息(也包括一些函数,如InitInstance或Create,这根本不是消息处理程序。然而,ClassWizard允许与在别处一样管理这些函数)。ClassWizard对所有可见的Windows只显示特定的几个项,这是基于“Class Info”页中的消息过滤器,它帮助我们把在特定的类中不常处理的消息选出来。如果想处理一个没有列出的消息,就试着换一个消息过滤器。 在“Object IDs”中列出的三个种类形的对象都是可以向类发送消息的控件。对于一些简单的控件按钮,我们只能接到有限的消息,如BN_CLICKED和BN_DOUBLECLIECKED。对复杂一些的对象,如编辑控件,就能处理许多不同的控件通知。当从“Object IDs”选择了菜单命令,如IDC_LOGIN时,就会在Message向看到两个入口,分别时BN_CLICKED(单击事件)和BN_DOUBLECLICKED(双击事件)。如果再选择BN_CLICKED,就会在“Member functions”项中看到与该事件对应的处理函数,“Edit Code”、“Delete Function”和“Add Function”分别指编辑,删除和添加给处理函数。 3.4.4 创建消息映射 当用AppWizard或ClassWizard产生了一个类时,Visual C+会为创建的类制造一个代码,以创建的一个消息映射。如果在ClassWizard之外创建了自己的CcmndTarget派生类,就要创建消息映射,首先应该在类说明之后增加下面一行: DECLARE_MESSAGE_MAP(); 消息映射由系列的宏创建,从BEGIN_MESSAGE_MAP()开始,以END_MESSAGE_MAP()结束。 1)填充消息映射 可以对不同类型的消息使用几个不同的宏来填充消息映射,包括消息范围。 ,预定义的Windows消息处理程序 对于许多标准Windows消息,在AFXMSG.H中体构了预定义的消息映射宏。这些宏名直接来自于消息ID,并且他们没有参数。例如WM_PAINT可以被宏ON_WM_PAINT()映射上来,并把WM_PAINT消息映射到类中的OnPaint()函数中。其他的标准Windows消息以相似的方式实现。 ,其他Windows消息 对于用户定义的消息或对没有默认处理的Windows命令,我们可使用宏ON_MESSAGE(),它带有消息ID和处理函数名: ON_MESSAGE(WM_USER+1,OnMyUserMessage)这些函数声明如下:afx_msg LRESULT OnMyUserMessage(WPARAM wparam,LPARAM lparam); ,命令消息 对于命令消息,可以使用ON_COMMAND宏,它采用ID命令和处理函数名,如下: ON_COMMAND(ID_FILE_NEW,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论