1、1猪 舍 初 级 环 境 远 程 监 控 系 统湖南省易普蓝科技有限公司猪舍初级环境监控系统的主要目的是帮助管理者掌控其需要了解的环境情况,并根据相关情况作出反应以实现智能化管理、调节猪舍环境。另外还带有报警功能。作品设计以监控室内温度、室内湿度、气体质量等变化的传感器为技术依托,以 STC-89C52 单片机为主控芯片展开研究,所体现的创新点在于运用逆向思维简化同类产品,降低生产成本,提高性价比,使之适用于环境质量要求不高的场合。同时,针对使用者的具体要求,作品可以实现监控参数调整、自动控制猪舍室内环境,或者根据需要向管理者发出报警,使之人为控制环境。随着网络技术的发展,网络速度的加快,远程
2、控制技术支持将逐渐占据技术支持的主流。系统讲述的是一个基于 Windows 而开发的远程控制程序,用到了 WinSock 的 API 技术。远程控制系统在文件管理方面采用了 FTP 技术支持,利用在被控端建立一个 FTP 客户端,在本地运行一个 FTP 服务器,通过利用FTP 技术来实现对目录查询,文件传输等文件操作。使文件管理能够简单实现!在直接控屏模块的实现过程中,客户端主要是负责向服务器端发出获取服务端屏幕图像数据的请求,把从服务器端发送来的屏幕图像在本地实时地显示出来,并且及时发送鼠标在本地显示图像的动作响应给服务器;而服务器端主要是负责响应客户端的请求并抓取与发送屏幕图像,响应客户端
3、发送过来的鼠标、键盘等的动作并反馈给客户端。从而实现了对远程计算机的直接控制屏幕的操作。市场上的产品大多有复杂化的趋势。产品监控数据繁琐、庞大,检测项目多,主要用于需要连续监控的场所。我们设计的猪舍初级环境监控系统主要具备以下功能:监控室内温度、室内湿度、气体质量。我们利用液晶显示器和矩阵键盘扫描技术,设计了参数调节功能,使控制器通过参数的处理,驱动风扇、加湿器、温度调节设施等设备完成对环境质量的调节,使之达到用户所需要的环境质量。2一、远程监控的意义(一)问题的提出(1)现代随着养猪业集约化和规模化程度的不断提高,对环境监测技术提出了新的技术需求和挑战,尤其是对现场各种信息的了解和掌握,是进
4、行现代化管理与调控的基础/基石;(2)猪舍环境数据采集十分困难:首先,涉及对象形式多样,要素复杂多变;其次,猪场往往偏远分散,通信条件差,信息获取难度大,自动化采集十分困难;(3)目前在总体上,国家“信息高速公路”网络已经建立,但对于农业与生态系统来说,综合信息的获取与通信仍存在“最后一公里”连接的瓶颈现象。(二)挑战和机遇(1)公共互联网(Internet)几乎无处不在:近年来,随着公共Internet 网络的普及和远程控制策略的完善,基于互联网平台的远程监控技术发展迅速。其具有的免维护特征大大降低了通信成本,广泛地延伸人类的工作空间。(2)无线移动技术发展迅猛:以 EPBE 协议无线传感网
5、络为代表的无线移动通信技术的普及应用,为农业环境远程监控“最后一公里”延伸,提供了重要的机遇。(3)信息采集“最后一公里”连接依然存在:从观测现场到数据使用者之间存在“最后一公里”连接的瓶颈,通过建立 Internet 与 EPBE 的无缝连接,是解决“最后一公里”连接的有效方案。(三)远程监控系统的几种解决方案3INTERNET用户 connectportX2 无线版 无线传感器嵌入式采集模块PC计算机 传感器系列有线远程监控模式无线远程监控模式(四)传统监控技术的局限性(1)从监测现场到使用者之间,需要线路连接,采用封闭式监控模式,对远离社区和偏僻的地带进行监测,不仅投入大,有时甚至在技术
6、上难以实现。(2)难以实现移动办公,现代管理人员经常出差,需要随时跟踪信息变化;跨地区,甚至跨国际间资料共享的,是现代信息社会必然的发展趋势,等等。(五)二种监控模式比较4数字量传送INTERNET监控计算机监控计算机数据采集控制设备传感器 1传感器2传感器NconnectportX2数据采集控制设备(无线版)传感器 1传感器 2传感器N传统模式:传输距离有限远程模式:距离无限系统采用 EPBE 无线通讯技术。EPBE 标准基于 802.15.4 协议栈建立,具备强大的设备联网功能,它支持三种主要的自组织无线网络类型,即星型结构、网状结构(Mesh)和簇状结构(Cluster tree) ,特
7、别是网状 MESH 结构,具有很强的网络健壮性和系统可靠性。MESH 网状网络结构特点:(1)系统采用多跳式路由通信;(2)网络容量很大;(3)可以跨越很大的物理空间,适合距离较远比较分散的结构;MESH 网状网络拓扑结构的网络具有强大的组网功能,网络所有实体只要在可视通讯范围内,都可以相互通信,如果没有直接通路,还可以通过“多级跳”的方式来通信;该拓扑结构还可以组成比较复杂的网络,除此之外,网络还具备自组织、自愈功能。无线传感网络技术优点(1)采用 EPBE 协议,低功耗、低成本、传感器之间相互感知、具有网络自组织能力、不需要固定基站,移动性强,比较适合农业监测特点。发展前景广阔。(2 EP
8、BE 无线传感网络安装方便,维护简单,使用寿命比较长,适合长时间不间断使用,应用 EPXB 模块使得通信距离得到了可靠的保障,组网方便,传输数5据稳定可靠。二、多功能无线远程监控系统系统基本功能 1。实现信息远程采集 2。信息远程传输:包括数据与图像 3。信息动态发布 4。形成网络共享数据库 5。提供远程决策诊断服务系统主要构成:现场采集单元、服务器端数据接收存模块、基于 Web 的数据管理模块。现场采集单元传感器 传感器基于EPXB模块的无线版无线传感装置传感器 传感器基于EPXB模块的无线版无线传感装置6现场数据采集与无线发送通过使用 X-CTU 软件对 EPXB 模块进行配置,使他在 c
9、onnectportX2 的 EPXB Network 中显示为 Wallrouter, EPXB 模块可以实现数据的 A/D 的转换,并无线发送数据。 EPXB 模块和网络协调器之间的数据传送是通过 ASP.NET 语言编程完成的。服务器端数据接收存储功能设计(1)服务器端数据接收存储模块,由监控中心 MS SQL Server 数据库服务器平台(2)和运行在数据库服务器上的数据接收存储程序,由 VB.NET C# 设计而成。基于 web 的数据管理模块Web 服务器采用 Windows 2003 服务器操作系统和 IIS 6.0 Web 服务器软件;应用 ASP.NET 技术规范,进行信息
10、网页发布,供用户查询浏览。 web 服务应用程序采用 B/S 结构(Brower/Server)三层体系结构。用户的操作则通过客户端浏览器(Brower)实现,主要业务处理在 Web 服务器端(Server)实现,数据存储、提取和更新等操作则在数据库服务器端实现。远程监控实时系统7硬件组成1)服务器平台:包括应用程序服务器和数据库服务器2)现场监控系统: 传感器系列,摄像头,数据采集与无线发送模块。3)传感器系列:已实现的包括: 空气温湿度,光照传感器,氨气浓度传感器。也可以选用市场上已有的各类传感器。也可以根据用户的要求填加其他类型传感器。4)摄像头:5)单片机:使用的是 STC-89C52
11、 型号的单片机,同时结合多种传感器及模块共同完成具有温度测量、湿度测量、气体质量测量、温度控制、湿度控制、风扇控制、液晶显示、报警提示等为一体的安全监控系统的初级设计。具体框架图如下:8以 AT89c51 单片机作为中央处理单元,控制各模块运行,使各模块组成一个系统,有机地结合起来,实现上述功能。在我们的设计中,温度传感器负责把物理温度信号转换成可识别的电信号,再把信号送给单片机识别、记录,并与用户设定的温度值进行比较,执行相应的程序,最后通过单片机控制开启风扇等措施调节温度。湿度传感器同温度传感器一样具有信号转换的作用。只是让单片机所处理的工作是控制加湿器。同样的道理,可然性气体的检测也遵循
12、这样的设计规则,使单片机与传感器之间形成类似于“传感器单片机加湿器传感器”这样一个闭环控制系统,达到智能化控制的目的。所设计的 4*4 矩阵键盘这是为了实现人与机器之间的交流设定参数,控制环境的质量这一功能。实现矩阵键盘的使用需要精心设计扫描程序,以实习用工作在最佳状态。当然,光靠矩阵键盘无法实现这样的功能。我们使用方便观察和显示效果比较好的 1602 液晶显示器作为显示设备。一来节约成本,二来在满足显示需求的同时缩小了作品的体积。已达到便于安装的目的。外储存器的使用主要用于实测数据的记录,具有掉电不掉数据的特点。同时外部储存器的使用也是解决单片机小内存的问题。外部储存器的设计重点也是集中在程
13、序控制上,以保障数据的准确性和录入误码率。外部连接器件主要是用于控制室内环境。当然他们的工作都是在传感器、单片机的基础上开展的。主要同他们一块实现循环控制的闭环系统。1三、远程控制系统远程控制是在网络上由一台电脑(主控端 Remote/客户端)远距离去控制另一台电脑(被控端 Host/服务器端)的技术,这里的远程不是字面意思的远距离,一般指通过网络控制远端电脑,不过,大多数时候我们所说的远程控制往往指在局域网中的远程控制而言。当操作者使用主控端电脑控制被控端电脑时,就如同坐在被控端电脑的屏幕前一样,可以启动被控端电脑的应用程序,可以使用被控端电脑的文件资料,甚至可以利用被控端电脑的外部打印设备
14、(打印机)和通信设备(调制解调器或者专线等)来进行打印和访问互联网,就像你利用遥控器遥控电视的音量、变换频道或者开关电视机一样。不过,有一个概念需要明确,那就是主控端电脑只是将键盘和鼠标的指令传送给远程电脑,同时将被控端电脑的屏幕画面通过通信线路回传过来。也就是说,我们控制被控端电脑进行操作似乎是在眼前的电脑上进行的,实质是在远程的电脑中实现的,不论打开文件,还是上网浏览、下载等都是存储在远程的被控端电脑中的。远程控制软件一般分两个部分:一部分是客户端程序 Client,另一部分是服务器端程序 Server,在使用前需要将客户端程序安装到主控端电脑上,将服务器端程序安装到被控端电脑上。它的控制
15、的过程一般是先在主控端电脑上执行客户端程序,像一个普通的客户一样向被控端电脑中的服务器端程序发出信号,建立一个特殊的远程服务,然后通过这个远程服务,使用各种远程控制功能发送远程控制命令,控制被控端电脑中的各种应用程序运行,我们称这种远程控制方式为基于远程服务的远程控制。通过远程控制软件,我们可以进行很多方面的远程控制,包括获取目标电脑屏幕图像、窗口及进程列表;记录并提取远端键盘事件(击键序列,即监视远端键盘输入的内容);可以打开、关闭目标电脑的任意目录并实现资源共享;提取拨号网络及普通程序的密码;激活、中止远端程序进程;管理远端电脑的文件和文件夹;关闭或者重新启动远端电脑中的操作系统;修改 W
16、indows 注册表;通过远端电脑上、下载文件和捕获音频、视频信号等。系统就是基于此而设计开发的,能实现以下的基本的远程功能:1) ,查看被控制端的文件目录清单;2) ,查看被控制端的文件内容;3) ,拷贝被控制端的文件到控制端;4) ,强迫被控制端重新启动或关机;25) ,修改被控制端的系统配置文件;6) ,直接执行任何可执行命令,打开应用程序;7) ,锁住(解锁)被控制端的屏幕,键盘和鼠标;8) ,控制被控制端的屏幕,在本地直接操作被控制端计算机;9) ,隐藏共享被控制端的硬盘;10) ,同时可以做到被控端的服务器自动运行及隐藏等功能;而且做了一些必要的安全性考虑。1.系统功能分析本程序是
17、由客户端和服务器端两部分组成的。而且需要客户端和服务器端同时运行相应的程序来实现的。系统要实现的基本功能可以简化如下:第一步,服务器端运行相应的远程控制软件服务器程序,使服务器端的某个端口处于监听状态(系统端口设置为 4069) 。这样服务器端计算机就时刻处于监听远程计算机连接请求的状态。第二步,当服务器端程序运行后,客户端在本地计算机中运行相应程序的客户端程序,运行这个客户端程序时,会指定一个要连接的服务器的 IP 地址和端口, (系统初始化的服务器地址是 192.168.0.6,端口:4069) ,程序运行后,点击连接就会向所有的网络搜索指定的计算机了。第三步,搜索到所指定的计算机后,客户
18、端计算机就向服务器端指定的端口发送连接请求(系统使用 TCP 连接) ,如果服务器端计算机同一端口处于监听状态,则服务器端接收客户端的连接请求,并根据设定的值向客户端发送接受请求确认信号,并同时向客户端发出登录成功信息确认对话框。第四步,客户端输入登录信息并确认后,就会向服务器端发送,服务器端接收到客户端发来的用户信息后,就开始对客户端所输入的客户进行合法性确认,如果不符合登录条件,则拒绝用户的连接。第五步,如果服务器端确认客户端所输入的用户符合服务器端计算机的条件,则服务器端允许客户端进行进一步的连接,这样,整个软件的连接过程就完成了。2.系统软件模型 在系统设计中,采用典型的 C/S 结构
19、,由客户端与服务端两部分构成。客户/服务器模式的最显著特点是非对等作用,即客户相对于服务器处于不平等的地位,服务端提供服务,客户端提供请求。结构如图 2.1 所示:3Server Client网络服务响应服务请求图 2.1 在设计客户端和服务器时,由于功能需求不同,我设计的客户端界面简单,面向对象,并且由相应的帮助文件,易于操作。而服务器端主要实现控制功能实现。而且不能让用户强行关闭,界面就简单,而且要做到隐藏。其他详细的功能模块描述将在第四章具体功能模块实现中给予描述。以下两章详细介绍了本程序的实现的基础和过程:3 相关技术客户/服务器技术是当今比较流行与具有发展的技术之一。以之构成的客户、
20、服务器应用系统具有系统结构优化、资源利用率高、整体运算速度快的优点,因而得到了广泛的应用。在 WINDOWS 应用程序中,处理实时通讯最常用到的还是 MICROSOFT 公司提供的 WinSock 控件。3. 1 WinSock 基本概念网络客户/服务器模式的原理是一台主机提供服务(服务器),另一台主机接受服务(客户机)。作为服务器的主机打开一个端口并进行监听, 如果有客户机向服务器的这一端口提出连接请求, 服务器上的相应程序就会自动运行,来应答客户机的请求。而 WinSock 的正确使用,给设计者带来了极大的方便,使得各种应用程序能够在Windows 环境下顺利进行各种网络通讯。3.1.1
21、Socket 引入20 世纪 80 年代初,美国政府的高级研究工程机构(ARPA)给加利福尼亚大学Berkeley 分校提供资金,让他们在 UNIX 操作系统下实现 TCP/IP 协议。在这个项目中,研究人员为 TCP/IP 网络通信开发了一个应用程序接口(API)。这个 API 就称为 Socket接口。今天,Socket 接口是 TCP/IP 网络最通用的 API,也是在 Internet 上进行应用开发最为通用的 API。实际上,Socket 在计算机中提供了一个通信端口(套接口)。通过这个端口,一台计算机可以与任何一台具有 Socket 接口的计算机通信。通信的基础是套接口。一个套接口
22、是通信的一端,在这一端上可以找到与其对应的一个名字。一个正在被使用的套应用程序操作系统网络接口应用程序操作系统网络接口4接口都有它的类型和与其相关的进程,套接口存在于通信域中。一个讨套接口通常和同一个域中的套接口交换数据(数据交换也可以穿越域的界限,单这时一定要执行某种解释程序)。应用程序在网络上传输,接收的信息都通过这个套接口来实现。在应用开发种就像使用文件句柄一样,可以对 Socket 句柄进行读写操作。开始使用套接字编程之前,首先必须建立这些概念:网间进程通讯,服务方式,客户机/服务器模式。进程通信的概念最初来源与单机系统。由于每个进程都在自己的地址范围内运行,为保证量相互通信的进程之间
23、既互不干涉又能协调一致工作,操作系统为进程通信提供了相应设施,如 UNIX BSD 中的管道(Pipe) 、命名管道(Named Pipe)和软中断信号(Signal) 、UNIX System V 的消息(Message) 、共享存储区(Shared Memory)和信号量(Semaphore)等,但都仅限于用在本机进程之间的通信。网间进程通信要解决的是不同计算机进程间的相互通信问题(可把同机进程通信看成是其中的一个特例) 。为此,首先要解决的是网间进程标识问题,同一计算机上,不同进程可以用进程号(Process ID)作为唯一标识,但在网络环境下,各个计算机独立分配的进程号不能唯一的标识该
24、进程。例如,计算机甲赋予某进程号 48,在乙计算机中也可以存在 48 号进程,因此, “48 号进程”这句话就没有意义了。其次,操作系统支持的网络协议众多,不同的协议的工作方式不同,地址格式也不一样,因此,网间进程通信还要解决多重协议的识别问题。在网络分层结构中,各层之间是严格单向依赖的,各个层次的分工和协作集中体现在相邻层之间的界面上。 “服务”是描述相邻层之间关系的抽象概念,即网络中各层向紧邻上层提供的一组操作。下层是服务提供者,上层是请求服务的用户。服务的表现形式是原语(Primitive) ,如系统调用或库函数等。系统调用是操作系统内核向网络应用程序或高层协议提供的服务原语。在国际标准
25、化组织(ISO)的术语中,网络层及其以下各层又称为通信子网,只是提供点到点的通信,没有程序或进程的概念。而传输层实现的是“端到端”通信,引进网间进程通信概念,同时也要解决差错控制、流量控制、数据排序(报文排序)及连接管理等问题。为此提供不同的服务方式:面向连接(虚电路)的服务或无连接的服务。面向连接服务是电话系统服务模式的抽象,即每一次完整的数据传输都要经过建立连接,使用连接及终止连接的过程。在数据传输过程中,各数据分组不携带目的地址,而使用连接号(Connect ID) 。本质上,连接是一个管道,收发数据不但顺序一致,而且内容相同。其中 TCP 协议就提供面向连接的虚电路。无连接的服务是邮政
26、系统服务的抽象,每个分组都携带完整的目的地址,各分组在系统中独立传送。无连接服务不能保证分组的先后顺序,不进行分组出错的恢复与重传,不保证传输的可靠性。提供无连接的数据报服务的常用协议是 UDP 协议。在 TCP/IP 网络应用中,通信的两个进程间相互作用的主要模式就是客户机/服务5器模式(Client/Server) 。即客户向服务发出服务请求,服务接收到请求后,提供相应的服务。客户机/服务器模式的建立基于以下两点:首先,建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用;其次,网间进程通信完全是异步的,
27、相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为两者的数据交换提供同步,这就是基于客户机/服务器式的 TCP/IP。3.1.2 Socket 的类型TCP/IP 的 Socket 提供下列三种类型套接字。1) 流式套接字(SOCKSTREAM)如果想让发送出去的数据按顺序无重复地到达目的地,那么就需要使用流式套接字。流式套接字提供一种可靠的面向连接地传输方法。数据无差错,无重复地发送,而且按发送地顺序进行接收。不过对单个地数据报,还是对整个数据包,流式套接字都提供一种流式数据传输,流式套系在使用 TCP。此外,在数据传输时,如果连接断开,应用
28、程序会被通知。流式套接字内设流量控制,避免数据流超限;数据被看成字节流,无长度限制。FTP 使用这种。2)数据报套接字(SOCKE_DGRM)数据报套接字提供一种不可靠的,非连接的数据包(Packet)通信方式。在这里,”不可靠”是指发送一个数据包不能获得担保,也不能保证数据包按照发送的顺序到达目的地。数据包以独立包形式被发送,不提供无错保证,数据可能丢失或重复,并且顺序混乱。在实现上,同一分组数据报可能不止一次的被发送。对于 WinSock 的TCP/IP 实现,数据报套接字使用用户数据报协议(UDP) 。虽然在通常情况下,在同一台计算机傻瓜或在轻负载的局域网所连接的两台计算机的进程之间进行
29、通信时,可能不会出现数据包不被发送或没按照顺序到达及又重复发送的情况,但在编写应用程序时,应该注意检测意外发生的事件,应具备处理出现这些情况的能力。当然,如果为非常复杂的网络(如 Internet)编写通信应用程序,就应该考虑到数据报套接字的不可靠性。如果我们的应用程序没有处理好这个问题,它就有可能崩溃。尽管如此,数据报套接字在发送数据包或者记录形数据时仍然有用。另外,数据报套接字还提供向多个目的地发送广播数据包的能力。3 ) 原始套接字(SOCKE_RAW)该接口允许对较低层协议,如 IP,ICMP 的直接访问。它通常用于检验新的协议实现或访问现有服务配置中的新设备3.2 基本套接字函数调用
30、大多数的数据报套接字应用程序都使用一个规定的事件序列来完成客户应用程序与服务器应用程序间的通信,如图 3.1 所示:6图 3.1 首先,客户端和服务器端都要创建一个数据报套接字。接着,服务器调用bind()函数给套接字分配工人的端口(在开发应用程序时,这个公认的端口通常时指定的。例如本程序的端口就指定为 4069) 。这样,客户端和服务器端就使用同一个端口来表示服务器套接字。一旦服务器将公认的端口分配给了套接字,客户端和服务器端都能使用 sendto()和 recvfrom()来发送和接收数据报直到完成传输。然后调用closesocket()来关闭套接字。下面具体看从给定套接字的一个地址开始的
31、每一步工作时怎样进行的。3.2.1 创建套接字系统调用 socket()函数向应用程序提供套接字手段时的声明如下:SOCKET PASCAL FAR socket(int af, int type, int protocol);该函数有三个参数,其中参数 af 指定通信发生的区域,在 DOS,Windows 系统中支持AF_INET,它时网际网区域。参数 type 描述要建立套接字的类型。也就是指是流式套接字还是数据报套接字。参数 protocol 说明该套接字使用的协议,如果该参数为 0,则表示使用默认的连接模式。Socket()函数根据这三个参数建立一个套接字,并将相应的资源分配给它,同时
32、返回一个整形套接字句柄。3.2.2 指定本机地址当一个套接字用 socket()创建以后,bind()将套接字地址(主机地址和端口)与所创建Client Serversocket() socket()bind()sendto() recvfrom()recvfrom() sendto().closesocket();closesocket()7的套接字编号联系起来,即将名字赋予套接字。bind()声明如下:int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR *name, int namelen);bind()函数共有三个参数,其中参数
33、 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 指对方套接字地址结
34、构的指针,对方套接字地址长度由参数 namelen 说明。如果调有成功,返回 0;否则返回 SOCKET_ERROR。Accept()函数原型声明如下:SOCKETPASCAL FAR accept(SOCKET s, struct sockaddr FAR *addr,int FAR*addrlen);该函数也由三个参数,其中参数 s 为本地套接字句柄,在做 accept 函数调用的参数前要先调用 listen(),参数 addr 是指向客户方套接字地址结构的指针,用来接收连接实体的地址。addr 的确切格式由套接字创建时建立的地址簇决定。参数 addrlen 为客户方套接字地址的长度。如果
35、调用成功,accept()函数返回一个 SOCKET 类型的值。否则返回 INVALID_SOCKET。Socket(),bind(),connect(),accept()这四个套接字系统调用可以晚上一个完全的通信建立,包括协议,本地主机地址和端口,目的地址和端口。socket()指定协议元,他的用法与是否为客户机和服务器,是否面向连接无关,bind()指定本机地址和端口号,时面向连接的。在服务器方必须调用 bind()函数;3.2.4 监听连接建立连接以后,服务器端要调用 listen()函数,表明愿意接收连接,listen()要在accept()之前调用,原函数声明如下:int PASCA
36、L FAR listen(SOCKET s,int backlog);该函数有两个参数,参数 s 标志一个本地已建立单尚未连接的套接字句柄,服务器愿意从它上面接收请求。参数 backlog 表示请求连接队列的最大长度,用于限制排队的请求个数,目前最大值为 5。如果调用成功,listen()函数返回 0;否则返回SOCKET_ERROR。3.2.5 数据传输8当连接建立以后,就可以传输数据了,通常调用 send()和 recv()函数。send()函数原型声明如下:int PASCAL FAR send(SOCKET s,const char FAR *buf,int len,int flags
37、);共有四个参数,其中 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 并释放分配给该套接字的资源,coseso
38、cket()函数原型声明如下: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(双字节)类型数值,他指要使用
39、的WinSock 规范的最高版本。其中主版本在低位字节,副版本号在高位字节。第二个参数是指向 WSADATA 结构的指针。该结构里有成员 wVersion 规定 WinSock 的版本号,如果返回的 wVersion 成员中的版本号不能被应用程序所接受,我们就应该调用WSACleanup()并且退出应用程序。声明完套接字,接下来就可以用 socket()函数创建一个套接字,声明如下:SOCKET PASCAL FAR socket(int af,int type,int protocol);其中 af 指这个套接字要使用的 Internet 地址。参数 type 指所创建的套接字的类别。pro
40、tocol 指套接字使用的协议,如果为 0,就自动选择一个合适的协议。在 WinSock1.1 中,socket()采用如下调用:SOCKET myUDPSock =socket(AF_INET,SOCKET_DGRAM,IPPROTO_UDP)9流式套接字: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 n
41、amelen);其中 s 指要绑定的套接字句柄,addr 时一个地址结果 sockaddr_in,用来指定一个 IP地址,结构如下:Struct sockaddr_inShort 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
42、 *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
43、 sockaddr FAR *to ,int to len)。参数意义与 recvfrom()类似。3.3.3 使用流式套接字由于流式套接字使用的是基于连接的协议,所以,它要先建立连接,然后才能读数据,和数据报套接字一样,流式套接字也由 socket()函数来创建,而且,用时必须用bind()函数为他分配一个地址,在创建一个套接字时,使用流式套接字与数据报套接字唯一不同的是,socket()调用传递的是 SOCK_STREAM,而不是 SOCK_DGRAM。10当已经建立了套接字,并赋给它一个地址后,需要移植方法建立和客户端的连接,为了做到这一点,要使用监听连接。我使用了 listen()函数
44、,声明如下: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,这时,可以调用 WSAGe
45、tLastError()来得到更高关于错误的细节。原来的套系在将继续监听新的连接请求,新的请求可能会通过 accept()函数的再一次调用而获得。为了让服务器接受请求,必须先发送请求,客户端程序通过 connect()函数来做这一点的,原型声明如下:int connect(SOCKET s,const struct sockaddr FAR *name,int namelen);参数 sockaddr 和 namelen 用来指定要连接的套系在的地址和端口。传给 connect()函数的 sockaddr 结构和给服务器 bind()函数的 sockaddr 结构是一样的。一旦客户端和服务器端
46、建立了连接,就可以通过 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 用
47、来向缓冲区填入接收到的数据。对于套接字来说,如果数据按照输入的队列接收过来的,recv()函数返回读入数据的字节数,否则,recv()将返回 SOCKET_ERROR,并且WSAGetLastError()给出具体的错误。在默认的状态下,当套接字由 socket()函数创建后,它被设置为对 I/O 操作的阻塞状态。 就要用到 WSAAsyncSelect()函数。它预先在特定的时间发生时,指定一个送往应用程序的 Windows 消息。声明如下:intWSAAsyncSelect(SOCKET s,HWND hWnd,unsigned int wMsg long lEvent);参数 hWnd
48、指定将要发送消息的窗口句柄,这个消息时由参数 wMsg 指定的。通常 wMsg指定一个用户定义的消息 WM_USER+n 参数 lEvent 指定让 WinSock 发送消息的事件,这个值由以下状态通过操作符(|)结合而来:FD_READ 数据正等待被读入FD_WRITE 套接字正准备写数据11FD_OOB 带外数据正等待被读入。FD_ACCEPT 一个新来的连接正等待被接收。FD_CONNECT 套接字连接已经完成FD_CLOSE 套接字连接已经关闭。当完成一个套系在操作后,就要用 closesocket()函数将它关闭。3.4 windows 的消息系统Windows 程序时基于一种事件驱
49、动的编程模式,这就意味着应用程序所要做的大部分工作时随着 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 为窗口下的消息