通信网络程序设计章-课件2.ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《通信网络程序设计章-课件2.ppt》由用户(ziliao2023)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 通信 网络程序设计 课件
- 资源描述:
-
1、1第2章 程序设计基础2.1 函数函数2.2 句柄句柄2.3 事件与消息事件与消息2.4 进程与线程进程与线程2.5 通信模式通信模式2.6 通信服务通信服务2.7 通信方式通信方式2.8 工具方法工具方法小结小结2在初步建立网络以及网络程序设计的基本认识之后,读者对网络程序设计的大体轮廓也有所了解,本章将进一步介绍开展网络程序设计所要涉及的重要概念及面临的问题。具体将以容易入手的面向过程编程理念为起点,把后续学习需掌握的关键知识剥离出来并总结为八个方面分别进行介绍。本章首先介绍作为程序设计基本工具的函数和句柄;接着讲解Windows操作系统下事件与消息的概念和区别;继而介绍程序的两种量化程序
2、独立性的单位,即进程与线程;然后将对网络通信的模式、服务、方式进行归纳性的介绍;最后重点说明网络程序设计需要使用的工具和方法。3函数是程序设计中除了变量、表达式和控制语句之外最重要的代码部分。变量、表达式和控制语句的通用性很强(编程语言已经决定了其使用规则),但是函数却因为开发领域或开发目的的不同有很大的区别。函数是程序功能的最小单元,是应用程序、类、组件、控件等高层功能的个体单位,网络程序设计学习的核心之一就是学会使用开发工具提供的网络接口函数(有可能是被封装的函数)。下面介绍网络程序设计中经常会用到的几种函数类型。2.1 函函 数数42.1.1 2.1.1 基本函数基本函数许多程序设计语言
3、中,可以将一段逻辑独立的执行代码作为一个单独单元,这就是程序中的函数。如果函数的定义与使用没有什么特殊技术,则称之为基本函数,比如在C语言中:int max(int x,int y)return(xy?x:y);5这是一段比较两数大小的函数。一般情况下,函数通过输入参数或返回值与外部进行交互。C+程序设计中的函数可以分为两类:带参数的函数和不带参数的函数。这两种参数的声明、定义也不一样。带有(一个)参数的函数的声明:类型名标识符+函数名+(类型标识符+参数)/程序代码没有返回值且不带参数的函数的声明:void+函数名()6/程序代码 上面花括号内为函数体。如果没有返回值,类型名为void。有返
4、回值的返回值类型由类型名称标识符决定,如:int类型返回值为int,以此类推。类型名有:void、int、long、float、int*、long*、float*C/C+中的函数必须声明后才可以被调用。调用格式为:函数名(实参)7调用时,函数名后的小括号中的实参必须和声明函数时的函数括号中的形参个数相同。有返回值的函数既可以进行计算,也可以作为右值进行赋值。82.1.2 2.1.2 库函数库函数库函数,顾名思义就是把函数放到库里(通常是编译好的文件)。这些函数首先由一部分人(通常是软件开发商、高级程序员或程序员自己)编写完成放到一个文件里,并编译成二进制文件,供日后调用。通常库函数来自于标准库
5、、用户或第三方提供的库。由于版权原因,库函数的源代码一般是不可见的,但在它的头文件中,可以看到库函数对外的接口。可以以C语言为例来说明库函数的作用。C语言的基本语句十分简单,如果要使用C语言进行sin()或cos()三角函数计算,9就需要编写颇为复杂的程序,这时就可以调用C标准库函数。库函数极大地方便了用户,同时也补充了语言本身的不足。编程时应当尽可能多地使用库函数,这样既可以提高程序的运行效率,又可以提高编程的质量。102.1.3 API2.1.3 API函数函数API(Application Programming Interface)是应用程序编程接口,程序员可以通过API对操作系统和软
6、硬件资源进行调用,它由系统制造商提供(存在于SDK中,见2.8.2节)。为方便用户的开发,大型软件系统几乎都提供自己的API,如google API、Facebook API等。微软为视窗操作系统开发提供的就是Windows API,32位系统下的Windows API称为Win32 API。API不是抽象存在的,而是以一个个具体的API函数的形式存在于SDK中的,用户可以通过开发工具对其进行调用。因此,可以把API想象成一个资源库,它提供各式各样与系统服务有关的函数。11事实上,在Windows下运行的视窗应用(无论是哪种语言开发)最终都是通过(直接或间接)调用Windows API函数来完
7、成其功能的,因此,可以把Win32 API看成是最底层的服务。在Windows程序设计发展初期,Windows程序员所能使用的编程工具唯有Windows API函数。这些函数是Windows提供给应用程序与操作系统的接口,它们犹如“积木块”一样,程序员可以通过它们搭建出各种界面丰富、功能灵活的应用程序。但是,基于Windows API的开发比较复杂,程序员必须熟记一大堆常用的API函数,而且还得对操作系统有深入的了解。12然而随着软件技术的不断发展,在Windows平台上出现了很多优秀的可视化编程环境,程序员可以采用“所见即所得”的编程方式来开发具有精美用户界面和功能强大的应用程序。这些优秀的
8、可视化编程环境操作简单、界面友好(诸如VB、VC+、Delphi等),它们通过提供大量封装了底层API函数的类库和各种控件,并赋予其方便的使用方法,简化了Windows API的复杂操作,因而极大地加速了应用程序开发的过程。有了这些控件和类库,程序员便可以把主要精力放在程序整体功能的设计上,而不必过于关注技术细节。13但是,如果用户要开发更灵活、更实用、更具效率及个性化的应用程序,还是需要调用API函数。虽然类库和控件使应用程序的开发简单得多,但它们只提供Windows的一般功能,对于比较复杂和特殊的功能来说,使用类库和控件是难以实现的。同时,类库和控件对API的封装隐去了很多编程细节,这对初
9、学者非常不利,因此建议如果不是急于完成开发项目,还是从API函数的编程开始学习。API函数的数量非常多,仅Win32 API函数就数千个,程序员不必刻意地背每一个函数的用法,在需要的时候查API帮助或字典工具(参见2.8.2节)即可。14为了区别于用户自己声明的函数,API函数前面用符号“:”标识(该标识也可以省略),如::printf(Hello World!n);/或写成printf(Hello World!n);除了API函数之外,作为网络程序设计的补充Windows Socket2还提供了SPI(详见9.4节),以丰富网络通信。152.1.4 2.1.4 回调函数回调函数回调函数是通过
10、函数指针调用的函数。回调函数把自己的函数指针(地址)作为参数传递给另一个函数,供其调用。可见,回调函数不是由该函数的实现方直接调用的,而是在特定的事件或条件发生时由实现一方的函数调用的,这样就简化了调用过程并增加了调用的灵活性。因而,回调函数常用于对事件或条件进行快速响应。回调函数实现的机制是:(1)定义一个回调函数;(2)提供函数实现方在初始化时将回调函数的函数指针注册给调用者;16(3)当特定的事件或条件发生时,调用者使用函数指针调用回调函数,以对事件进行处理。这种机制对调用者与被调用者实现了分离,调用者不关心谁是被调用者,所有它需知道的只是存在一个具有某种特定原型、某些限制条件(如返回值
11、为int)的被调用函数指针。回调函数的声明如下:LRESULT CALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);CALLBACK是回调函数声明的关键词。17回调函数在网络编程中可用于网络事件通知机制,例如,有时要在网络程序中设置一个监控器,每当特定的事件到达,程序会得到相应的通知,之后会调用一个功能函数。通常情况下,通知机制的实现者对要调用的功能函数一无所知(无法预知用户要进行调用的什么功能),此时就需有一个特定原型的函数指针,用这个指针进行回调,来通知程序事件已经发生并执行设定的事件。这样的实例很多,如后面将要学到的NetBIOS中的NCB/MCB中的ncb
12、_event域(参见4.2.2节)、线程创建CreateThread()函数中的第二个形式参数(参见8.3.1节),都是对回调函数的应用。18回调函数的调用者对被调用者在何处,其传递的处理程序做了什么等都不关心,而只关心返回值,因为基于返回值,它将继续执行或退出。回调函数源自C语言,在C+中只用于与C代码建立接口,或用于与已有的回调接口打交道。针对上述情况,C+主要使用虚拟方法(参见10.1.3节)或函数符(functor),而不是回调函数。192.1.5 2.1.5 挂钩函数挂钩函数Windows操作系统是建立在事件驱动机制之上的,系统各部分之间通过传递消息互相沟通。一般情况下,进程只接受来
13、自它内部的或其他进程发送过来的消息。因此,为了能在应用程序中监控系统的各种事件消息,拦截在进程外传递的消息,Windows提供了挂接各种回调函数的功能,这种技术就被称为挂钩或钩子(HOOK)。挂钩技术是Windows操作系统提供的专门针对系统底层消息进行处理的一种机制,它的出现使得用户可以介入操作系统的内部,对底层进行开发。20它允许应用程序轻松地截获并处理Windows消息或者特定事件,实现普通应用程序难以实现的功能。钩子实际上是一个处理消息的代码段,它通过系统调用挂入系统,从而在合适的位置插入自己的代码扩展或改变原有系统的行为。通过钩子函数,用户可以监视自己的进程或其他进程发生的事件,在捕
14、捉到指定进程请求或返回的特定消息时,钩子函数可以在目标处理函数之前处理它,从而在系统级对所有的消息、事件进行过滤和修改。比如可以通过截获键盘输入的消息来获得键盘输入的信息等,同样还可以通过钩子函数强制结束消息的传递。21函数实现了对数据的操作,是程序的重要元件,学习网络程序设计实际上就是学习网络编程接口函数的过程。上述关于函数的介绍仅是初步的,除此之外的C+的成员函数、虚函数等其他内容,将结合后面的具体应用进行介绍。22在编程过程中,需要对Windows中的一些对象进行引用,一般的引用就是句柄。句柄是整个Windows编程的另一基础,一个句柄是指用于标识应用程序中的不同对象和同类对象中不同实例
15、的唯一整数值(一个32位的无符号整数),这个实例可以是诸如窗口、按钮、图标、滚动条、输出设备、控件或者文件等对象。2.2 句句 柄柄23应用程序能够通过句柄访问相应的对象的信息,Windows使用了大量句柄来标识其内部的很多对象。进一步分析,句柄就是一个标识符,用来标识对象或者项目。它就像我们的车牌号,每一辆注册过的车都会有一个确定的号码,不同的车其号码各不相同,即便是有两辆号码相同的车,它们也肯定在不同的时期出现。应用程序可以通过调用FindWindow()之类的API函数来获得一个它所关心对象的句柄,之后其他的函数就可以使用该句柄来引用该对象。24在Windows编程中会用到大量的句柄,比
16、如HINSTANCE(实例句柄)、HBITMAP(位图句柄)、HDC(设备描述表句柄)、HICON(图标句柄)等。最常用的就是窗口句柄HWND,窗口句柄就是CreateWindow()之类窗口创建函数的返回值hWnd(关于Windows窗口的具体创建过程参见6.6.2节)。下面函数就创建了一个窗口:HWND hWnd=:CreateWindowEx(0,szClassName,NULL,WS_POPUP|WS_SYSMENU|WS_SIZEBOX|WS_VSCROLL,100,100,300,300,0,0,hInstance,NULL);25该窗口成功创建后,后面的程序就可以通过hWnd来引
17、用这个窗口了。进一步分析,句柄实际上是一种指向指针的指针。应用程序启动后,组成这个程序的各对象是驻留在内存中的。由于Windows是一个以虚拟内存为基础的操作系统,在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,以此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找那个对象呢?为了解决这个问题,Windows操作系统为全体应用程序腾出一些内存单元,用来专门登记各应用程序的对象在内存中的地址的变化,而前者的物理地址在系统运行期间是始终保持不变的。26Windows内存管理器移动了对象在内存中的位置后,会把该对象新的地址及时地告
18、知给对应的句柄并进行更新。因此,只要知道这个句柄,就可以间接地知道对象具体在内存中的哪个位置了,这个地址是在对象装载(Load)时由系统分配给的,当对象卸载时(Unload)又释放给系统。27网络程序是交互功能很强的应用软件,不同用户、进程、线程、函数、对象间进行交互就必须要有相互通知的机制,这就要用到事件与消息。2.3 事事件件与与消消息息282.3.1 2.3.1 事件事件事件(Event)指的是由系统事先设定的、能被对象识别和响应的动作。事件是指对象对于外部动作的响应,当对象发生了某个事件,就会执行这个事件相应的代码,这段代码被称为“事件过程”。事件有系统事件和用户事件之分,系统事件由系
19、统激发,如每隔24小时,银行储户的存款日期增加一天;用户事件由用户激发,如用户点击按钮,在文本框中显示特定的文本。用户可以通过下面函数创建一个事件变量:HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,/安全属性29 BOOL bManualReset,/复位方式BOOL bInitialState,/初始状态 LPCTSTR lpName /对象名称);也可以使用OpenEvent()函数打开一个已经存在的事件句柄:HANDLE OpenEvent(DWORD dwDesiredAccess,/请求访问权限BOOL bInh
20、eritHandle,/句柄是否继承LPCTSTR lpName);/事件对象名30在事件变量的使用中应当注意:若指定的事件发生了,则事件变量被置位,处理完成之后,为了等候下一个事件的发生,事件变量需被复位。置位函数:BOOL SetEvent (HANDLE hEvent);/事件对象句柄复位函数:BOOL ResetEvent (HANDLE hEvent);/事件对象句柄31程序员使用等待函数可以监控事件是否被置位,这样的等待函数很多,下面的等待函数可以同时等待多个事件(事件数组)是否被置位。DWORD WaitForMultipleObjects(DWORD nCount,/内核对象的
21、数量CONST HANDLE*lpHandles,/内核对象句柄的数组的指针BOOL fWaitAll,/等待方式标识DWORD dwMilliseconds);/等待超时时间等待过程中,WaitForMultipleObjects()在dwMilliseconds时间段内处于阻塞态。当32WaitForMultipleObjects()因事件触发返回时,返回值是事件数组(由指针lpHandles指向)中导致该函数返回的事件在数组中的索引值。除了WaitForMultipleObjects(),可以用于等待事件置位的API函数还有WaitForMultipleObjectsEx()、WaitF
22、orSingleObject()、WaitForSingleObjectEx()等。332.3.2 2.3.2 消息消息消息是软件对象(这里指具有某种完整功能的个体)之间进行交互作用和通信的手段。通常认为,单一的一个对象是无用的,只有对象间的交互作用,程序才可以获得高阶的功能以及更为复杂的行为。举例来说,一部自行车在无人使用时,就是一堆铝合金和橡胶,没有任何作用;而只有当有其他的对象(人)来和它交互(骑)的时候,它才是有用的。软件对象与其他对象进行这样的交互与通信是利用发送给其他对象消息来实现的。34消息必须包含适量的信息。当对象A想让对象B来执行一个B中的方法(函数)时,对象A就会发消息给对
23、象B,而B需要更多的信息才可能知道该如何正确地完成A的请求。比如,当你想改变自行车的齿轮,就必须指出哪个齿轮,改变的指标是什么。这个信息将作为消息的参数传递过来。消息的地位非常重要,Windows就是利用消息来驱动操作系统工作的,具体介绍参见2.8.1节。352.3.3 2.3.3 事件与消息的区别事件与消息的区别Windows程序开发交互功能的完成主要是基于事件和消息的,二者极易被程序员混淆。消息是Windows操作系统底层支持的,在Windows SDK的开发中,涉及消息循环的处理函数;而事件是基于消息的,是消息到达后触发的。消息发送给操作系统,让操作系统处理消息处理函数;而事件触发时程序
24、立刻调用事件处理函数。二者的区别可以总结为以下三点:(1)含义区别。事件用来描述程序的运行状态或环境的改变,例如鼠标移动、用户按键、窗口状态的改变、时钟计时、线程结束等。36消息实际上是一种通信的机制,操作系统往往会利用消息来通知应用程序某个事件的发生,但这并不意味着消息与事件就是一一对应的或者说是相当的。例如,应用程序完全可以自己直接监视某个事件的发生并对其做出响应,而不依赖于消息;反之,应用程序也可以在没有事件发生的情况下发送消息,如:在完成通信的某个功能或者模拟一次事件时。通俗地讲,事件就是“当的时候”,消息就是“嗨!你该干了”。(2)来源区别。事件只能由用户通过外设的输入产生;而产生消
25、息的来源有三个,即由操作系统产生,由用户触发的事件转换而来,由另一个消息(属于一个应用程序)产生。37(3)激活方式区别。消息是由客户操作产生给服务者,而事件是操作系统处理消息的过程中反馈的结果。事件和消息的区别与联系还需读者在具体的编程过程中逐步体会。了解了句柄、消息、事件、函数,再加上掌握了编程语言提供的变量、控制语句、判断语句,读者编写具有基本功能的Windows应用程序就不存在障碍了。38进程与线程可以理解成量化程序独立性的两个单位,在后续的学习中会被反复提及,二者既有区别又有联系,在进行网络编程时要合理利用。2.4 进进程程与与线线程程392.4.1 2.4.1 进程与线程的定义进程
展开阅读全文