




免费预览已结束,剩余38页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于自定义协议中间件的设计与实现摘 要随着internet的迅速发展,网络的应用程度越来越大,越来越多的程序需要通过网络实现,因此网络通信逐渐成为软件重要的一部分。CORBA、SOAP等协议为我们进行网络编程简化了很大一部分的工作,但是这些协议给我们提供便利的同时也存在一些缺点。CORBA庞大复杂,并且技术和标准更新很慢,SOAP的缺点是由于浏览器的超时时间配置是不宜设置过长而可能对某些耗时较多的操作容易出现“超时”的现象。而且由于SOAP是基于HTTP协议的,所以每个操作都是单独、互不相关的,对于某些需要若干子功能叠加在一起的大功能来说,实现起来不大方便。并且现在软件产品要在不同平台、不同网络环境以及不同公司的产品之间平滑地运行,所以使用中间件是最好的解决方案。通过中间件程序员可以忽略不同平台、不同网络环境等产生的影响,而只关注于业务逻辑。KESCP协议的特点是可以自定义,支持压缩、加密等功能。针对SOAP一些无法解决的问题在设计上进行了一定的考虑。采用KESCP可以执行由终端主动发起的操作,有较强的可扩展性。该协议建立在传输层之上应用层之下,充当一个消息中间件。通过该协议程序员可以方便地编写程序,只关注于业务逻辑而不用直接跟Socket接触。自定义通信协议中的数据包结构保留了一些字段以便扩展,并且数据包中的数据长度可以是变长的。该自定义通信协议全部采用ANSI C标准来写,可以在Windows、Linux、Unix、XPE、Windows CE等操作系统上运行。同时本系统也为C/C+与Java间通信提供了一个解决方案,可以方便地在C/C+与Java间通信。关键词:自定义协议 中间件 网络通信AbstractAs the developing of the internet, most of the program application has to use the network communication. The TCP/IP becomes to be a most useful standard. The CORBA and SOAP protocol can let us reduce much work of programming, but they also have some disadvantages. The CORBA is very complex and the update of its standard is very slow. The SOAP is not suitable to do the time-consuming operation and since its based on HTTP, its not convenient to do the operation which is combined by many modules.We make a dynamic communication protocol to let programmers easy to develop the application. The dynamic communication protocol called KESCP which is support the function of compress, encrypt and some other functions. We can add our dynamic function into the KESCP.By the use of the KESCP, we have the standard interface to be invoked. We use the ANSI C to develop the KESCP and it can run on almost all the platform, including Windows NT, Linux, UNIX, Windows CE.net, Windows XPE. We also provide the solution on communication between C and Java.Keywords: Dynamic Protocol Middleware Network Communication目录第一章 引言11.1网络协议介绍11.1.1OSI参考模型11.1.2TCP/IP模型31.2中间件简介51.2.1Client/Server应用模式51.2.2分布式系统结构61.2.3中间件71.3项目背景81.4项目需求91.5专用术语说明9第二章 KESCP协议的总体设计102.1KESCP协议设计原则102.2KESCP协议结构102.3模块工作流程112.4KESCP子系统模块与功能122.4.1KESCP子系统模块结构122.4.2KESCP子系统接口13第三章 数据包格式设计183.1数据包定义183.2结构体字节对齐问题193.3字节顺序问题203.4结构体中数据变长问题21第四章 网络编程224.1Socket编程224.2Windows网络编程234.3Linux下Socket编程254.4Java Socket编程274.5C发送数据给Java274.6Java发送数据给C29第五章 KESCP协议接口30第六章 程序结果32第七章 结束语34致谢 35参考文献36ContentsChapter 1 Introduction11.1Network Protocol11.1.1OSI11.1.2TCP/IP31.2Middleware51.2.1 Client/Server pattern51.2.2 Distribute pattern61.2.3 Middleware71.3Project background81.4Requirement91.5Special term9Chapter 2 Summary design of KESCP102.1Design principle102.2Structure102.3Flow112.4Modules of KESCP122.4.1Structure of modules122.4.2Interface of modules13Chapter 3 Data Packet183.1Data Packet183.23.2 Structure of the C struct193.3Byte order203.4Dynamic data of the struct21Chapter 4 Socket224.1Socket224.2Windows Socket234.3Linux Socket254.4Java Socket274.5Data transfer from C to Java274.6Data transfer from Java to C29Chapter 5 API of KESCP30Chapter 6 Demonstration32Chapter 7 The end34Acknowledgement35Reference3636第一章 引言1.1 网络协议介绍计算机的网络通信在硬件底层实际上是二进制位1和0得点对点传送机制1。为了方便程序员,定制了一套复杂的软件,为应用程序提供方便的高层接口。这种软件自动处理大部分底层通信的问题,使程序员们可以忽略大部分通信的问题。通信涉及的所有部分必须采用同一套机制,通过相同的信息交换规则,通信才能成功完成。人们把这种认同称为协议,也就出现了网络协议或通信协议的说法。网络协议设计者把通信问题划分称多个子问题2,每个子问题用一个模块来解决,各个模块可以是一个子协议。这样把整个通信协议划分称多个子协议,通过相互分离的多个子模块来解决通信协议的大部分问题。这使得通信协议的设计、开发、处理以及扩展性等方便有了很大的增强。但是各个模块也不是完全独立的,模块之间是相互联系的。各个协议组合在一起称为协议系列或协议族。分层模型是其中最好的方法之一。分层模型描述了把通信问题划分成几个子问题的方法,一个协议系列可通过对应的一层规定一个协议来设计。1.1.1 OSI参考模型国际标准化组织定义了一个七层参考模型3,如图1.1所示:图1.1 OSI参考模型OSI参考模型的全称是开放系统互连参考模型(Open System Interconnection Reference Model, OSI/RM),在OSI七层模型中,每一层为其上一层提供服务,并为其上一层提供一个访问接口。不同主机之间的相同层次称为对等层。如主机A中的表示层和主机B中的表示层互为对等层,主机A中的网络层和主机B中的网络层互为对等层。主机用各个层组成的协议栈来接收和发送数据。OSI参考模型各个层的作用:1. 物理层(Physical Layer)物理层规定了激活、维持、关闭通信端点之间的机械特性、电气特性、功能特性以及过程特性。该层为上层协议提供了一个传输数据的物理媒介。数据传输的单位是比特(bit)。属于物理层的典型规范代表有:RS-232、RS-449、V.35、RJ-45等。2. 数据链路层(Data Link Layer)数据链路层在不可靠的物理介质上提供可靠的传输,该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。数据的单位为帧(Frame)。属于该层的代表有:SDLC、HDLC、PPP、STP、帧中继等。3. 网络层(Network Layer)网络层负责对子网间的数据包进行路由选择,网络层还可以实现拥塞控制、网际互连等功能。数据单位为数据包(Packet)。网络层协议的代表有:IP、IPX、RIP、OSPF等。4. 传输层(Transport Layer)传输层是第一个端到端,即主机到主机的层次。传输层负责将上层数据分段并提供端到端的、可靠的或不可靠的传输。此外,传输层还要处理端到端的差错控制和流量控制问题。数据的单位为数据段(Segment)。传输层协议的代表有:TCP、UDP、SPX等。5. 会话层(Session Layer)会话层管理主机之间的会话进程,即负责建立、管理、终止进程之间的会话。会话层还利用在数据中插入检验点来实现数据的同步。会话层的协议包括:NetBIOS、ZIP等。6. 表示层(Presentation Layer)表示层对上层数据或信息进行变换以保证一个主机应用层信息可以被另一个主机的应用程序理解。表示层的数据转换包括数据的加密、压缩、格式转换等。表示层协议的代表包括:ASCII、ASN.1、JPEG、MPEG等。7. 应用层(Application Layer)应用层为操作系统或网络应用程序提供访问网络服务的接口。应用层协议的代表包括:Telnet、FTP、HTTP、SNMP等。1.1.2 TCP/IP模型ISO制定的OSI参考模型的过于庞大、复杂招致了许多批评。与此对照,由技术人员自己开发的TCP/IP协议栈获得了更为广泛的应用。在TCP/IP参考模型中,去掉了OSI参考模型中的会话层和表示层(这两层的功能被合并到应用层实现)。同时将OSI参考模型中的数据链路层和物理层合并为主机到网络层。TCP/IP模型与OSI参考模型对比4如图1.2所示:图1.2 TCP/IP模型与OSI模型对比TCP/IP模型各个层次的功能如下:1. 网络层实际上TCP/IP参考模型没有真正描述这一层的实现,只是要求能够提供给其上层-网络互连层一个访问接口,以便在其上传递IP分组。由于这一层次未被定义,所以其具体的实现方法将随着网络类型的不同而不同。2. 网络互连层网络互连层是整个TCP/IP协议栈的核心。它的功能是把分组发往目标网络或主机。同时,为了尽快地发送分组,可能需要沿不同的路径同时进行分组传递。因此,分组到达的顺序和发送的顺序可能不同,这就需要上层必须对分组进行排序。网络互连层定义了分组格式和协议,即IP协议(Internet Protocol)。网络互连层除了需要完成路由的功能外,也可以完成将不同类型的网络(异构网)互连的任务。除此之外,网络互连层还需要完成拥塞控制的功能。3. 传输层在TCP/IP模型中,传输层的功能是使源端主机和目标端主机上的对等实体可以进行会话。在传输层定义了两种服务质量不同的协议。即:传输控制协议TCP(transmission control protocol)和用户数据报协议UDP(user datagram protocol)。TCP协议是一个面向连接的、可靠的协议。它将一台主机发出的字节流无差错地发往互联网上的其他主机。在发送端,它负责把上层传送下来的字节流分成报文段并传递给下层。在接收端,它负责把收到的报文进行重组后递交给上层。TCP协议还要处理端到端的流量控制,以避免缓慢接收的接收方没有足够的缓冲区接收发送方发送的大量数据。UDP协议是一个不可靠的、无连接协议,主要适用于不需要对报文进行排序和流量控制的场合。4. 应用层TCP/IP模型将OSI参考模型中的会话层和表示层的功能合并到应用层实现。应用层面向不同的网络应用引入了不同的应用层协议。其中,有基于TCP协议的,如文件传输协议(File Transfer Protocol,FTP)、虚拟终端协议(TELNET)、超文本链接协议(Hyper Text Transfer Protocol,HTTP),也有基于UDP协议的。1.2 中间件简介中间件技术5是伴随着网络而发展起来的一种面向对象的技术。网络出现后,Client/Server模式迅速发展,但许多软件需要在不同公司的网络产品、硬件平台、网络协议等不同环境下运行,Client/Server模式就没办法解决这个问题,因而中间件诞生了。中间件是位于操作系统和应用软件之间的服务,它的主要作用是用来屏蔽网络硬件平台的差异性和操作系统与网络协议的异构性,使应用软件能够平滑地运行在不同的平台上。同时中间件在负载平衡、连接管理和调度方面起了很大的作用,使企业级应用的性能得到了大幅提升,满足了关键业务的需求。1.2.1 Client/Server应用模式传统的应用系统模式是“客户机/服务器”模式(如图1.3所示),客户机/服务器模式的结构是把一个大型的计算机应用系统变为多个能互为独立的子系统,而服务器是整个应用系统资源的存储与管理的中心,多台客户机则各自处理相应的功能。随着Internet的迅速发展,这种传统的模式已经不能适应新的环境,于是就产生了新的分布式应用系统。图1.3 C/S模式图1.2.2 分布式系统结构随着中间件技术的发展,企业级的应用已经从简单的C/S系统向多层体系结构不断发展,三层结构是最常用的多层应用。在三层体系结构中,各层次按以下方式进行划分,实现明确分工:1. 表现层(View tier):提供简洁的人机交互界面,完成数据的输入输出。2. 商业逻辑层(Business tier):完成业务逻辑,实现客户与数据资源对话的桥梁。同时还实现分布式管理、负载均衡、安全隔离等。3. 企业信息系统层(Enterprise Information System tier):处理企业信息系统软件,包括:ERP、DBMS等。三层结构的典型模型图如图1.4所示:图1.4 三层体系结构图1.2.3 中间件中间件是位于中间的软件,是处于系统软件和应用软件之间的一类软件,中间件的结构如图1.5所示:图1.5 中间件结构图中间件6不是一种软件,而是一类软件。它不仅可以实现互连,还可以实现应用之间的互操作,屏蔽了底层操作系统的复杂性,使得程序开发人员面对一个简单而统一的开发环境,减少程序设计的复杂性,将注意力集中在自己的业务逻辑上。中间件可以分为以下六种:1. 终端仿真与屏幕转换中间件这类中间件用以实现客户机的图形用户接口和现有的服务器字符接口的应用程序间的互操作。它用于早期的大型机系统,现以基本上不用。2. 数据库中间件这类中间件适用于应用程序与数据源之间的互操作,是应用最广泛、最成熟的一种。ODBC是常见的一个例子,它为数据库访问提供一系列的API接口。3. 远程过程调用中间件RPC是早期分布式应用中常用的一种同步式的请求应答协议。通过RPC程序员编写客户端应用可以直接去引用它,而不用了解底层信息。4. 消息中间件越来越多的分布式应用系统采用消息中间件来构建,通过消息中间件的使用,可以把应用扩展到不同的操作系统和不同的网络环境中,简化了应用之间数据的传输,提供可靠的、跨平台的消息传输手段。5. 对象中间件面向对象中间件提供一个标准的构件框架,使不同公司的软件通过不同的地址空间、网络和操作系统互相交互访问。6. 交易中间件交易中间件是专门针对联机交易处理系统而设计的,通过交易处理系统可以大大减少开发一个联机交易处理系统的编程量,常用于银行业务系统、订票系统等。目前,市场上常用的三种中间件技术7是:OMG组织制定的CORBA标准、Microsoft的COM标准和SUN公司的J2EE。1.3 项目背景由于公司的“管理工具”产品需要大量地在客户端与服务器端进行交互,所以底层网络通信成为系统的一个关键部分,底层通信模块关系到上层各个模块的实现,而底层会由于不同平台、不同网络环境等产生影响,所以需要一个中间件来解决程序员开发过程中的问题。 “管理工具”产品在被管理端是用C/C+实现的,而在管理端则是基于J2EE的B/S架构,所以底层通信要求在C/C+与Java间通信。SOAP协议使得我们可以将注意力集中在具体的业务逻辑而不再是底层的通讯协议上,在Java端可以很方便地调用SOAP协议,在C/C+端也可采用开源的gSoap项目来实现。但是该协议的缺点是由于浏览器的超时时间配置是不宜设置过长而可能对某些耗时较多的操作容易出现“超时”的现象。而且由于是基于HTTP协议的,所以每个操作都是单独的和互不相关的,对于某些需要若干子功能叠加在一起的大功能来说,实现起来不大方便。因此,我们就定义一个自定义通信协议来实现底层通信模块,这样底层通信模块也可以充当一个中间件,可以方便地让其他公司来调用,我们也可以方便地管理其他公司的产品。1.4 项目需求该自定义通信协议必须实现以下功能:l 在C与Java之间通信l 保证数据安全、准备地传输l 平台无关性,要在Linux、Unix、Windows下正常运行l 提供统一接口,以便第三方产品调用l 可扩展性,方便以后扩展1.5 专用术语说明术语说明SOAP简单对象访问协议,具有很好的扩展性KESCP自定义通信协议的名字终端8终端也叫瘦客户机,指采用专用嵌入式处理器和精简版操作系统并留有闪存接口、基于PC工业标准设计的小型专用商用PC,有Linux终端、Unix终端、Windows CE终端、Windows XPE终端等第二章 KESCP协议的总体设计2.1 KESCP协议设计原则KESCP协议是建立在TCP/IP模型的传输层之上应用层之下,利用传输层提供的可靠传输,减少了自己在编写通信协议传输可靠性方面的工作,并且不用害怕自己编写的协议不可靠。KESCP协议利用Socket机制来进行通信,利用各个平台现有的Socket API来实现通信过程,虽然不同操作系统平台下Socket API会有差别,但基本上都大同小异,只要在实现的过程中按各个不同平台来处理即可。这样通过KESCP协议程序员在编写应用程序的时候就不用考虑不同平台之间的差别,也可以方便地在不同平台间进行数据传输。KESCP在TCP/IP模型中所处的层次如图2.1所示:应用层KESCP传输层Internet层网络层图2.1 KESCP协议栈如图1.2所示,TCP/IP的传输层为隐藏了很多底层的实现,方便了我们的使用,KESCP协议使用传输层提供的TCP协议来实现通信,我们把KESCP中TCP传输的过程封装起来,为应用程序提供统一的API,这样KESCP就封装成一个或多个.DLL文件,充当一个中间件。如图1.5所示,我们只要利用Socket接口,实现中间件的功能,定义统一的API。用户只能看到KESCP提供的API,方便地在上层应用程序中调用,这样就增强了代码的重用性和耦合性,这也正是中间件的优势。2.2 KESCP协议结构KESCP协议采用分层嵌套的结构9,通过采用分层嵌套结构可以清晰地把协议中的各个模块独立开来,同时也方便了协议功能的扩展。KESCP协议的结构图如图2.2所示:图2.2 KESCP结构图KESCP协议通过把明文数据包进行加工处理,可以保证数据传输的安全、准确。为了让通信双方固定KESCP处理模块,我们定义了一个32位的标识符,其中每个模块占1位,如包含了该模块功能则该位置1。KESCP协议可包含32个处理模块,可以通过位操作符方便地判断协议中包含哪些处理模块。其中处理模块1为压缩解压缩处理模块,采用开源的zlib库来实现;处理模块2为加密解密处理模块,采用开源的OpenSSL库来实现。2.3 模块工作流程KESCP协议要用于客户端与服务器端之间交互,所以KESCP协议必须包含“主动模式”和“被动模式”10,处理流程如图2.3所示:图2.3 模块流程图每个处理模块应该提供统一的接口,以实现组件化的功能。2.4 KESCP子系统模块与功能2.4.1 KESCP子系统模块结构按照功能将KESCP协议实现拆分成:1. 网络监听模块(Listener)2. 网络接收/发送模块(Transfer)3. 加载模块(Loader)打包/解包模块(Packer)4. 各个附加的子模块(暂时只实现SM_Crypt, SM_Compress这两个模块,并且附加的子模块对外部不可见)。KESCP子系统模块图如图2.4所示:图2.4 KESCP子系统模块图2.4.2 KESCP子系统接口 网络监听模块(Listener)模块名称Listener功能描述网络监听模块,是网络数据处理的第一步性能描述接口与方法/初始化HRESULT KESCP_Init();参数说明无返回值S_OK(0) : 成功E_FAIL(0x80000008L) : 失败处理流程略/开始在指定端口进行监听HRESULT KESCP_StartListen(in unsigned short port);参数说明port : 监听的端口返回值S_OK(0) : 成功E_FAIL(0x80000008L) : 失败处理流程一旦监听端发现有连接,则会对应生成一个Ireceiver接口对象进行相应的工作,并将该对象加入内部Ireceiver列表末尾。/停止监听工作HRESULT KESCP_StopListen( in unsigned short port);参数说明port : 需要停止监听的端口返回值S_OK (0): 成功E_FAIL(0x80000008L): 失败处理流程略/初始化HRESULT KESCP_UnInit();参数说明无返回值S_OK(0) : 成功E_FAIL(0x80000008L) : 失败处理流程略 网络发送/接收模块(Transfer)模块名称Transfer功能描述实现网络接收功能性能描述接口与方法/主动查询该前端是否收到新的数据HRESULT KESCP_GetNewMsg(out void* ppBuf);参数说明ppBuf : 如果该前端模块收到了数据还未处理,则返回相应的数据首指针,如果有多个数据包,一次只返回一个.返回值S_OK(0) : 成功E_FAIL(0x80000008L) : 失败处理流程略./发送数据HRESULT KESCP_SendBack(in void* pBuf);参数说明pBuf : 需要通过该前端送出的数据返回值S_OK(0) : 成功E_FAIL(0x80000008L) : 失败处理流程略./释放空间HRESULT KESCP_FreeBuffer(in void* pBuf);参数说明pBuf : 由Recv()函数产生的指针.返回值S_OK(0) : 成功E_FAIL(0x80000008L) : 失败处理流程释放内存. 打包/解包模块(Packer)内部模块模块名称Packer功能描述按从高到低的顺序对数据进行解包,或者从低到高对数据进行打包.每个接收/发送模块都要对应一个独立的Packer实例.性能描述接口与方法/进行解包工作HRESULT KESCP_Unpacking( in unsigned long ulFlag, in void* pOriginal,out void* ppResult);参数说明ulFlag : 外部模块标志pOriginal : 需要解包的数据ppResult : 解包后的结果返回值S_OK(0) : 成功E_FAIL(0x80000008L) : 失败处理流程根据ulFlag,按照逆序将数据解包/进行打包工作HRESULT KESCP_Packing(in unsigned long ulFlag, in void* pOriginal,out void* ppResult);参数说明ulFlag : 外部模块标志pOriginal : 需要打包的数据ppResult : 打包后的结果返回值S_OK(0) : 成功E_FAIL(0x80000008L) : 失败处理流程根据ulFlag,按照顺序将数据打包 加载模块(Loader)模块名称Loader功能描述对子模块进行加载,每个Packer模块都要有一个Loader实例.性能描述接口与方法/加载模块前的初始化工作HRESULT KESCP_LoadInit();参数说明无返回值S_OK(0) : 成功E_FAIL(0x80000008L) : 失败处理流程略/加载模块HRESULT KESCP_Load();参数说明无返回值S_OK(0) : 成功E_FAIL(0X80000008L) : 失败处理流程按顺序加载各个模块./结束前的清理工作HRESULT KESCP_LoadUnInit ();参数说明无返回值S_OK(0) : 成功E_FAIL(0X80000008L) : 失败处理流程略第三章 数据包格式设计3.1 数据包定义由于KESCP协议是个双向传输的协议,所以在定义数据结构12的时候,要注意双方格式的对称。这样可以有效降低双方的维护,同时为了考虑日后可能兼容UDP数据传输,故定义时,参考了现有的IP数据包的格式进行定义,具体定义结构如下:数据包格式:基本信息(4字节)目标地址(20字节)源地址(20字节)数据长度(4字节)校验码(4字节) 数据(变长)数据包格式说明:定义备注HEAD.INFO(4 bytes)Type(1 byte)标识是否是我能够处理的数据类型,管理工具的type均为0x12Protocol(1byte)KESCP协议的协议编号为0x01Version(1 byte)“管理工具”的KESCP版本定为0x03Reserved(1byte)保留用,同时为了字节对齐。HEAD.ADDRADDR Dest(20 bytes)目标机器地址ADDR Src(4bytes)发起方机器地址HEAD.OTHERLen(4 bytes)后边接的实际数据长度Checksum(4 bytes)数据段的校验(采用CRC32校验)Data(变长)要发送的数据数据包格式C语言定义:定义typedef struct tagKESCPunsigned long info;ADDR dest;ADDR src;unsigned long len;unsigned long checkSum; char data1;KESCP;说明checkSum数据校验只针对要发送的数据进行校验,不对数据包头部数据进行校验数据部分只定义一个字符数组空间,根据数据的长度通过对结构分配相应的空间来保存数据定义typedef struct tagADDRunsigned long ver;union unsigned char add44; unsigned char add616;addr;ADDR;说明兼容IPv4和IPv6的网络地址的数据结构。其中针对IPv4的版本是4;针对IPv6的版本是6;如果是IPv4,则通过addr4访问其具体的地址;如果是IPv6,则通过addr6访问其具体的地址。3.2 结构体字节对齐问题为了能使CPU对变量进行高效快速地访问,变量的起始地址应该具有某些基本特性13,即所谓的“字节对齐”。如4字节的int型变量,其起始地址应位于4字节边界上,即起始地址能被4整除。32位系统的变量字节对齐规则如下:char在字节边界上对齐;short在双字节边界上对齐;int、long、float在4字节边界上对齐;double在8字节边界上对齐。结构体的成员变量由于字节对齐而导致结构体内的变量不一定分配在连续内存空间,即中间可能存在空的内存空间。一些编译器有扩展指令用于设置结构体字节对齐的方式,如VC下的#pragma pack()指令,但不同的编译器的扩展指令不同就会导致程序的可移植性降低。兼顾到各个平台字节对齐设置不一样以及KESCP协议数据基本都是采用4字节的数据类型,所以我们统一设定KESCP协议采用4字节对齐。我们可以通过以下指令来设置字节对齐:#pragma pack(push)#pargma pack(4) .#pragma pack(pop)3.3 字节顺序问题由于机器芯片实现上的差别,数据在内存中存储就存在两种格式14:big endian和little endian。如0x12345678这个数据,在不同机器中存储是不同的,如下表所示:Big endianLittle endian0字节0x120x781字节0x340x562字节0x560x343字节0x780x12Intel芯片采用的是little endian,而Motorola的PowerPC系列CPU、TCP/IP网络传输中以及Java虚拟机中都是采用big endian。C/C+在通信时,一般都是直接将内存中的数据拷贝到输出中,这样,在输出的字节流中一个整形量的各个字节就是按照其在内存中顺序输出的。而目前常用的x86平台上,整形变量是按照小字节优先的顺序保存的,即数据的低8位保存在开头的第一个字节中,数据的高8位保存在最后一个字节中,比如32位(4字节)整形量0x00123456,其在内存中的实际存储就是0x56 0x34 0x12 0x00。这样,其在通信的输出也是0x56 0x34 0x12 0x00。 在一般情况下,网络通信的两端往往都是C/C+,所使用的机器平台也都是x86平台,字节顺序并不会产生什么问题。 但是当一端是C,另一端是java时,就会出现问题。因为Java为了保证平台无关性,其整形变量在进行I/O操作时会自动转换为大字节优先顺序输出,比如32位整形量0x00123456的实际输出是0x00 0x12 0x34 0x56,恰好和x86平台上的C程序是反过来的!因此,当C程序和Java程序进行通信时,必须有一端首先对其输入或输出的信息进行字节顺序的转换,使两端数据的字节顺序一致,才能保证数据的正确性。 因此在KESCP协议中我们在C端进行转换,当要发送数据时把数据都转换成big endian格式,当接收到数据时把数据还原成little endian格式,这样就确保了数据的统一。我们可以利用Socket API提供的4个函数:htonl()htons()ntohl()ntohs()3.4 结构体中数据变长问题在自定义通信协议的时候,我们要发送的数据通常情况下是变长的,这就给我们设计结构体带来了麻烦。因为不能在结构体里面存放指针,也不能设计一个固定大小的数组。如结构体中存在指针则实际上发送过去的是一个4字节的地址,而不是指针指向的数据。所以我们把结构体最后一个成员设为长度为1的数组,如下:typedef struct tagKESCPunsigned long info;ADDR dest;ADDR src;unsigned long len;unsigned long checkSum; char data1;KESCP;其中data成员以及data后连续的内存空间用来保存实际要发送的数据。数据的长度通过为结构体分配相应的空间(数据前面部分固定的长度 + 实际要发送的数据长度),这样就能动态地生成结构体。第四章 网络编程4.1 Socket编程TCP /IP 是计算机互连最常使用的网络通讯协议15,TCP /IP 的核心部分由网络操作系统的内核实现,应用程序通过编程接口来访问TCP /IP。套接字(Socket)是介于网络应用层和传输层之间的编程接口,套接字接口提供了访问下层通信协议的大量系统调用和相应的数据结构。用Socket编写客户端与服务端TCP通信的流程图如图4.1所示:图4.1 客户端与服务端Socket TCP通信流程图4.2 Windows网络编程Windows网络编程16大多是采用Winsock标准接口,通过Winsock接口可以实现与协议无关的程序,现有Winsock1和Winsock2两个版本。WinSock编程分为服务器端和客户端两部分,TCP服务器端的大体流程如下:对于任何基于WinSock的编程17首先必须要初始化WinSock DLL库。int WSAStartup(WORD wVersionRequested,LPWSADATA lpWsAData)wVersionRequested是我们要求使用的WinSock的版本。调用这个接口函数可以初始化WinSock 。然后必须创建一个套接字(Socket)。SOCKET Socket(int af,int type,int protocol)套接字可以说是WinSock通讯的核心。WinSock通讯的所有数据传输,都是通过套接字来完成的,套接字包含了两个信息,一个是IP地址,一个是Port端口号,使用这两个信息,就可以确定网络中的任何一个通讯节点。当调用了Socket()接口函数创建了一个套接字后,必须把套接字与你需要进行通讯的地址建立联系,可以通过绑定函数来实现这种联系。int bind(SOCKET s, const struct sockaddr FAR* name, int namelen)struct sockaddr_inshort sin_family ;u_short sin_prot ;struct in_addr sin_addr ;char sin_sero8 ;就包含了需要建立连接的本地的地址,包括地址族、IP和端口信息。sin_family字段必须把它设为AF_INET,这是告诉WinSock使用的是IP地址族。sin_prot就是要用来通讯的端口号。sin_addr就是要用来通讯的IP地址信息。在这里,必须还得注意一下有关大头(big-endian)小头(little-endian)的问题。因为各种不同的计算机处理数据时的方法是不一样的,Intel X86处理器上是用小头形式来表示多字节的编号,就是把低字节放在前面,把高字节放在后面,而互联网标准却正好相反,所以,必须把主机字节转换成网络字节的顺序。WinSock API提供了几个函数把主机字节转化成网络字节的函数:u_long htonl(u_long hostlong)u_short htons(u_short hostshort)把网络字节转化成主机字节的函数:u_long ntohl(u_long netlong)u_short ntohs(u_short netshort)这样,设置IP地址和port端口时,就必须把主机字节转化成网络字节后,才能用Bind()函数来绑定套接字和地址。当绑定完成之后,服务器端必须建立一个监听的队列来接收客户端的连接请求。int listen(SOCKET s, int backlog)这个函数可以把套接字转成监听模式。如果客户端有了连接请求,我们还必须使用int accept(SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen)来接受客户端的请求。现在基本上已经完成了一个服务器的建立,而客户端的建立的流程则是初始化WinSock,然后创建Socket套接字,再使用int connect(SOCKET s, const struct sockaddr FAR* name, int namelen) 来连接服务端。下面是一个最简单的创建服务器端和客户端的例子:服务器端的创建:WSADATA wsd;SOCKET sListen;SOCKET sclient;UINT port = 8000;int iAddrSize;struct sockaddr_in local , client;WSAStartup( 0x11 , &wsd );sListen = Socket ( AF_INET , SOCK_STREAM , IPPOTO_IP );local.sin_family = AF_INET;local.sin_addr = htonl( INADDR_ANY );local.sin_port = htons( port );bind( sListen , (struct sockaddr*)&local , sizeof( local ) );listen( sListen , 5 );sClient = accept( sListen , (struct sockaddr*)&client , &iAddrSize );客户端的创建:WSADATA wsd;SOCKET sClient;UINT port = 8000;char szIp = ;int iAddrSize;struct sockaddr_in server;WSAStartup( 0x11 , &wsd );sClient = Socket ( AF_INET , SOCK_STREAM , IPPOTO_IP );server.sin_family = AF_INET;server.sin_addr = inet_addr( szIp );server.sin_port = htons( port );connect( sClient , (struct sockaddr*)&server , sizeof( server ) );当服务器端和客户端建立连接以后,无论是客户端,还是服务器端都可以使用 int send( SOCKET s,const char FAR* buf,int len,int flags)int recv( SOCKET s,char FAR* buf,int len,int flags)函数来接收和发送数据,因为,TCP连接是双向的。当要关闭通讯连结的时候,任何一方都可以调用int shutdown(SOCKET s,int how)来关闭套接字的指定功能,再调用int closeSocket(SOCKET s)来关闭套接字句柄,这样一
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 餐饮店租赁权及品牌使用权转让及加盟合同范本
- 边疆古代手工业考古合同
- 物业管理公司车位使用权转让合同范本
- 安全生产标准化要素有哪些
- 建设工程开工前质量安全条件核查表
- 幼儿园安全自查总结
- 安全管理绩效考核细则
- 美术下雨天课件
- 安全事故案例反思总结
- 工程安全事故等级划分
- 嘟嘟少儿英语beep演示简化版
- GB/T 699-2015优质碳素结构钢
- GB/T 19250-2013聚氨酯防水涂料
- GB/T 19096-2003技术制图图样画法未定义形状边的术语和注法
- GB/T 13808-1992铜及铜合金挤制棒
- 项目安全体系图
- 中央财政科技计划的项目结题审计指引讲解文课件
- 职业暴露(锐器伤)应急预案演练脚本
- 首届全国报刊编校技能大赛决赛试卷(一)及答案
- 材料出入库表格范本
- DB14∕T 2442-2022 政务数据分类分级要求
评论
0/150
提交评论