欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    网络程序设计基本知识.ppt

    • 资源ID:6141066       资源大小:537.50KB        全文页数:172页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    网络程序设计基本知识.ppt

    第6章 网络程序设计基本知识,6.1 网络应用程序的概念6.2 TCP/IP应用程序工作模型与网络编程接口6.3 套接口的概念及其编程原理6.4 Winsock API基本函数套接口与连接的建立6.5 Winsock API基本函数数据传输6.6 Winsock API基本函数连接与套接口的关闭习题,6.1 网络应用程序的概念,6.1.1 什么是网络应用程序我们设计的应用程序可以简单地分为两种:一种程序不需要使用其他程序产生的数据并且其他程序也不使用它输出的数据;另一种程序需要与其他的应用程序进行数据交换才能完成其功能,也就是说程序之间存在通信问题。进程间通信的问题也可以分为两种:一种是在操作系统中论述的单机系统中进程间的通信问题,另一种一般是在不同系统的进程间通过网络通信协议进行的进程间的通信问题。,6.1.2 网络应用程序的标识问题同一系统中不同进程间进行通信时,通过系统分配的进程号(Process ID)就可以惟一标识一个进程。也就是说,要通信的进程只要知道对方的进程号就可以进行通信。而网络情况下进程间的通信问题就要复杂得多,不能只简单地用进程号来标识不同的进程,因为各主机都独立地分配其进程号。为了惟一地标识网络中通信的一个进程(即通信的某一方),就要使用一个如下的三元组:(本地协议,本地IP地址,本地端口号),这样一个三元组由于它只指定了通信时一条连接的半个部分,即通信的一方,因而称为半相关(Half-association)。如果要完整地表示网络中进行通信的两个进程,那么就要使用一个如下结构的六元组:(本地协议,本地地址,本地端口号,远地协议,远地地址,远地端口号)在互联网中通信的两台主机在网络层都只能使用IP协议,但在网络层之上可以选择使用TCP协议或UDP协议,这样就可能得到以下4种类型的相关六元组:(本地TCP协议,本地IP地址,本地端口号,远程TCP协议,远程IP地址,远程端口号);,(本地UDP协议,本地IP地址,本地端口号,远程UDP协议,远程IP地址,远程端口号);(本地TCP协议,本地IP地址,本地端口号,远程UDP协议,远程IP地址,远程端口号);(本地UDP协议,本地IP地址,本地端口号,远程TCP协议,远程IP地址,远程端口号)。如果通信的两端使用不同的协议(后两类六元组),根据前面我们所学的知识,由于TCP协议和UDP协议使用的协议格式大不相同,通信时双方在传输层不能相互识别对方送来的数据,也就不可能进行正常的通信,因此后两种情况是不存在的。,换句话说,通信的两个进程在端到端的传输层只能使用相同的协议,因此一个完整的网间通信就可以简化为用一个五元组来标识通信的两个进程:(协议,本地IP地址,本地端口号,远程IP地址,远程端口号)6.1.3 客户/服务器模型 1客户/服务器模型的特点客户/服务器模型的通信方式从所具有的资源角度来说,有明显的非对称性。服务器拥有较多的资源,它具有运算能力强,数据存储容量大,通信速度快,系统的可靠性高等优点。相对来说,客户则拥有较少的资源,它在各方面的性能一般要比服务器差。,客户/服务器模型在工作时,要求有一套客户机和服务器能共同识别的规则或约定,用来保证服务器方可以识别客户提出的请求是什么,客户方也能够解释收到的服务器应答。从本质上来说,这其实就是服务器方和客户方在通信中所使用的一套协议,它必须在通信的两端都被实现。根据实际情况,协议可能是对称的也可能是非对称的。在对称的协议中,每一方都有可能扮演主从角色;在非对称协议中,一方被不可改变地认为是主机(服务器),而另一方则是从机(客户机)。,2服务器的分类根据服务器提供服务方式的不同,服务器可以分为串行服务器和并发服务器。串行服务器只有一个进程用串行的方式对客户的请求提供服务;并发服务器可以为请求的每一个客户创建一个进程或线程,然后由对应的进程或线程给每一个客户提供服务。并发服务器又可以分为预先创建服务子进程(或线程)和按需创建服务子进程(或线程)两种方式。根据上面的分析,我们来总结一下客户/服务器模型的特点。对于服务器方来说:服务进程一般在启动后就一直运行,以等待客户请求的到来,除非服务被禁止或执行强迫终止服务程序。,服务器方进程使用的是众所周知的端口,否则客户无法知道提供服务的端口,也就不可能提出服务的请求。服务器方通常拥有较多的资源(对称方式除外)。服务器方进程可以并行处理多个客户的请求,当然可以同时处理的客户请求数目是有一定限制的。服务器方在通信时属于被动的一方。对于客户方来说:在需要服务时向服务器提出请求,请求的服务得到满足并完成处理任务后,就终止客户程序的执行。,使用向系统申请的临时端口(如10245000之间)与服务器方进程进行通信。拥有相对较少的资源(对称方式除外)。客户方在通信时属于主动的一方。,6.2 TCP/IP应用程序工作模型与网络编程接口,6.2.1 TCP/IP应用程序工作模型使用TCP/IP协议的网络,其协议核心内容在层次结构的低三层,即网络接口层、IP层和传输层,而这三层的功能一般是由操作系统的内核来实现的。如图6-1所示的是两台主机的进程间通过网络编程接口进行通信的原理图。,图6-1 TCP/IP应用程序工作模型图,图6-1所示的是使用TCP/IP协议网络的典型应用方式,即客户/服务器模式。通过图6-1用户还要明白一个问题,网络程序设计其实是使用系统提供的网络协议完成用户程序的功能,即在网络应用程序中使用网络协议提供的服务,而不是让用户去实现网络协议各层的功能。,6.2.2 Windows Sockets简介1Windows Sockets的概念Windows Sockets是在Windows环境下使用的一套网络编程规范,常常简称为Winsock。2Windows Sockets的来源Sockets本来是Unix操作系统下流行的一种网络编程接口(API),它是1983年在Berkeley(加州大学伯克利分校)4.2 BSD操作系统中被首先引入的,因此被称为“Berkeley Socket API”。,3Windows Sockets的版本目前常用的Winsock有两个版本:一个是16位的Winsock 1.1,由动态链接库WINSOCK.DLL提供支持;另一个是32位的Winsock 2.2,由动态链接库WSOCK32.DLL提供支持。4Winsock API函数的分类在Winsock规范中把Winsock API函数集分为与BSD Socket(用在Unix中)相兼容的基本函数、网络数据信息检索函数和Windows专用扩展函数三类。,Winsock规范的核心内容是符合Berkeley Socket风格的库函数,但为了使程序员能充分利用Windows消息驱动机制进行编程,又定义开发了一组针对Windows的扩展库函数。Windows Sockets规范中针对Windows的扩展部分,为应用程序开发者提供了开发Windows应用软件的功能,它有利于程序员写出更加稳定并且更加高效的程序。另外,除了WSAStartup()和WSACleanup()两个函数外(在6.5节介绍),其他Windows扩展函数的使用不是强制性的。,各种Windows平台支持的 Winsock 版本 Windows 95 1.1(2.2)Windows 98 2.2 Windows Me 2.2 Windows NT 4.0 2.2 Windows 2000 2.2 Windows XP 2.2 Windows CE 1.1,5Windows Sockets对多线程的支持Windows Sockets支持多线程的Windows进程。一个进程可以包含一个或多个同时执行的线程(在Windows 3.1非多线程版本中,一个任务对应了一个仅具有单个线程的进程)。6.2.3 Windows Sockets规范的目标及几个相关的概念1Windows Sockets规范的目标Windows Sockets规范的目标有两个:一是给网络应用程序的开发者提供一套简单的网络编程API;二是让各家网络软件供应商能够根据这套规范建立各自的符合Windows Sockets标准的实现和应用程序。,此外,在一个特定Windows版本的基础上,Windows Sockets也定义了一个二进制接口(ABI),以此来保证应用Windows Sockets API的应用程序能够在任何网络软件供应商的符合Windows Sockets协议的实现上工作。2Windows Sockets兼容和Windows Sockets提供者遵守Windows Sockets规范的网络软件称之为是Windows Sockets兼容的,而Windows Sockets兼容实现的提供者称之为Windows Sockets提供者。一个网络软件供应商必须百分之百地实现Windows Sockets规范才能做到与Windows Sockets兼容。,3Windows Sockets应用程序任何能够与Windows Sockets兼容实现协同工作的应用程序都被认为是具有Windows Sockets接口的,称这种应用程序为Windows Sockets应用程序。应用程序通过调用Windows Sockets的API实现它们之间的相互通信。Windows Sockets又利用下层的网络通信协议功能和操作系统调用来实现实际的通信工作。,6.3 套接口的概念及其编程原理,6.3.1 套接口(Socket)Windows Sockets API依靠套接口(Socket)进行通信。套接口可以看成是两个网络应用程序进行通信时,各自通信连接中的一个端点。通信时,其中的一个网络应用程序将要传输的一段信息写入它所在主机的Socket中,该Socket通过网络接口卡(NIC)的传输介质将这段信息发送到另一台主机的Socket中,使这段信息能传送到其他程序中,如图6-2所示。,图6-2 套接口示意图,现在我们根据图6-2来分析一下使用套接口进行通信的过程。当主机A(Host A)上的网络应用程序(Program A)要发送数据时,通过调用数据发送函数首先将要发送的一段信息写入其Socket中,Socket中的内容通过主机A的网络管理软件由主机A的网络接口卡发送到主机B(Host B),主机B的网络接口卡接收到这段信息后,再传送给主机B的网络管理软件,网络管理软件将这段信息保存在主机B的Socket中,然后程序B(Program B)才能在Socket中读取并使用这段信息。,从以上的通信过程可以看出,如果不考虑通信过程中的网络接口卡和传输介质等,则网络通信的过程就是由数据的发送者将要发送的信息写入一个套接口,再通过中间环节将信息传输到接收端的套接口中,然后就可以由接收端的应用程序将信息从套接口中取出。因此,两个应用程序之间的数据传输要通过套接口来完成。在学习了后面更多的内容后我们将会体会到,套接口的本质是通信过程中所要使用的一些缓冲区及一些相关的数据结构。,6.3.2 套接口的分类为了满足不同的通信程序对通信质量和性能的要求,一般的网络系统提供了三种不同类型的套接口,以供用户在设计网络应用程序时根据不同的要求来选择。这三种套接口分别是:(1)流式套接口(SOCK_STREAM)。(2)数据报套接口(SOCK_DGRAM)。(3)原始套接口(SOCK_RAW)。,流套接字(SOCK_STREAM):用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议TCP。这类套接字中,传输数据之前必须在两个应用进程之间建立一条通信连接,这就确保了参与通信的两个应用进程都是活动并且响应的。当连接建立之后,应用进程只要通过套接字向TCP层发送数据流,而另一个应用进程便可以接收到相应的数据流,它们不需要知道传输层是如何对数据流进行处理。特别需要注意的是通信连接必须显式建立。该套接字类型适合传输大量的数据,但不支持广播和多播方式。,数据报套接字(SOCK_DGRAM):提供了一种无连接的服务,通信双方不需要建立任何显式连接,数据可以发送到指定的套接字,并且可以从指定的套接字接收数据。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP进行数据的传输。由于数据包套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。与数据报套接字相比,使用流式套接字是一个更为可靠的方法,但对于某些应用,建立一个显式连接所导致的系统开销是令人难以接收的,并且数据报套接字支持广播和多播方式。,原始套接字(SOCK_RAW):与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包流套接字只能读取TCP的数据数据报套接字只能读取UDP的数据。使用原始套接字的主要目的是为了避开TCP/IP处理机制,被传送的数据包可以被直接传送给需要它的应用程序。因此,其主要是在编写自定义底层协议的应用程序时使用,例如各种不同的TCP/IP实用程序(如ping和arp)都使用原始套接字实现,也可以用来实现数据包捕捉分析等。,6.3.3 套接口编程原理该过程可以分为以下几个阶段:(1)电信局必须要有一个电话总机,相当于套接口通信机制中提供服务的服务器。在Socket中通过调用socket()函数来开启一个服务,即创建一个提供服务的套接口。(2)电信局必须给电话总机分配一个号码(如114,即查号服务的号码是114),以便用户通过拨该号码得到电话服务,同时接入该电信局的用户必须知道该总机的号码。,(3)电信局114查号台下会开设一些自动服务的分机,但是它们的数量是有限的。总机开通后就一直在监听(listen)用户的拨号,用户拨打114时,可能拨通,得到服务;也可能拨不通,就会听到忙音。同样,我们在建立一个Socket服务时,也会调用listen()函数来监听客户的请求。(4)对于用户来说,如果知道电信局的查号号码,在想得到查号服务时就可以拨打114,请求得到电信局的服务,这相当于在客户端要进行的操作。,(5)电信局的总机接受了某用户拨打的电话后,负责把用户与一个分机连通,而总机本身则又回到等待状态,等待其他客户的请求。(6)服务完成后,挂上电话,线路断开,一次服务过程结束,否则该线路将一直被占用,浪费了通信资源。在服务器和客户之间,最后也要使用closesocket()函数关闭套接口,释放该套接口上的有关资源,这可以由通信的任何一方或双方同时提出。,6.3.4 Winsock套接口编程时对错误的处理机制 用户编写网络应用程序时,出现错误是不可避免的,因此对错误的检查和控制至关重要,一个好的或者说成功的Winsock应用程序应该尽可能地检测和处理各种错误。对Winsock函数来说,返回错误是很常见的。与大多数系统调用类似,Winsock函数发生的错误也有两种。不成功的Winsock函数调用返回的最常见的值是宏定义SOCKET_ERROR,在Winsock的头文件中(如Winsock2.h),它的数值是1。,该函数的使用非常简单,格式如下:int WSAGetLastError(void);这是一个无参函数,调用时返回最新发生的网络错误代码。调用该函数时要注意,当一特定的Windows Sockets API函数指出一个错误已经发生时,就应该调用本函数来获得对应的错误代码。WSAGetLastError()函数返回的这些错误都已预定义成常量值,根据Winsock版本的不同,这些值的声明不在Winsock1.h中,就在Winsock2.h中。这两个头文件的惟一差别是Winsock2.h中包含的错误代码(针对Winsock 2而引入的一些新的API函数)更多。为各种错误代码定义的常量(带有#定义的宏)一般都以WSAE开头。,6.3.5 网络字节顺序不同的主机对字节值的存储顺序不同。在存储由多个字节组成的一个字时,有的计算机在起始地址处存放整数的低序号字节,这种存储格式叫“小序在前”(Little-endian);而有的计算机在起始地址处存放整数的高序号字节,这种存储格式叫“大序在前”(Big-endian)。计算机究竟采用那种字节存储顺序由各自的设计决定,如Windows系列的操作系统使用的是小序在前的存储方式,而Sun OS和Solaris等采用的大序在前的存储方式。,在计算机中,TCP/IP协议使用的16位整数(如端口号)和32位整数(如IP地址)是按计算机各自的“主机字节”(Host-byte)来表示的。在网络中,为了保证数据的正确性,网络通信协议中必须指定网络字节顺序。如果在网络中使用IP地址和端口号,按“互联网联网标准”的要求,指定的多字节值必须用“大序在前”的形式来表示,一般称之为“网络字节”(Network-byte)顺序。,在Winsock中,有一系列的函数可用于多字节数的转换,把它们从主机字节顺序转换成网络字节顺序,反之亦然。下面4个API函数便将一个数从主机字节顺序转换成网络字节顺序:htonl():参数是主机字节顺序的一个4字节数,函数返回网络字节顺序的数;WSAHtonl():参数是主机字节顺序的一个4字节数,函数返回网络字节顺序的数;htons():参数是主机字节顺序的一个2字节数,函数返回网络字节顺序的数;WSAHtons():参数是主机字节顺序的一个2字节数,函数返回网络字节顺序的数。,6.4 Winsock API基本函数套接口与连接的建立,6.4.1 打开WinsockWSAStartup()应用程序或DLL只能在一次成功的WSAStartup()调用之后才能进一步调用其他的Windows Sockets API函数。1函数格式WSAStartup()函数的格式如下:int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);,2函数参数说明wVersionRequested:此参数是一个WORD型(双字节型)数值,它指定准备在应用程序中要使用的Winsock库的版本号。其中,用高位字节指定副版本,用低位字节指定主版本。就目前的Win32平台而言,Winsock 2库的最新版本是2.2(Win95为Winsock 1.1)。如果需要加载Winsock 2.2版,指定此参数的值为0 x0202;也可使用宏MAKEWORD(X,Y),其中X为高位字节,Y为低位字节,如MAKEWORD(2,2)。lpWSAData:此参数是一个指向WSADATA结构的指针。当该函数被调用时,它返回关于Windows Sockets实现的详细信息,该结构的定义如下:,typedef struct WSADataWORD wVersion;WORD wHighVersion;Char szDescriptionWSADESCRIPTION_LEN+1;Char szSystemStatusWSASYS_STATUS_LEN+1;unsigned short iMaxSockets;unsigned short iMaxUdpDg;char FAR*lpVendorInfo;WSADATA,FAR*LPWSADATA;,各字段的含义说明如下:wVersion:调用者希望使用的Winsock版本号;wHighVersion:加载的Winsock库所支持的最高Winsock版本,通常和wVersion的值相同;szDescription:系统加载的Winsock库的说明字符串,如“Winsock 2.0”;szSystemStatus:系统状态或配置信息的说明字符串;iMaxSockets:套接口的最大编号(该字段被Winsock 2或其后的版本忽略);,iMaxUdpDg:UDP数据报的最大容量(该字段被Winsock 2或其后的版本忽略);lpVendorInfo:厂商专有信息(该字段被Winsock 2或其后的版本忽略)。3函数返回信息WSAStartup()函数的返回值是一个整数,如果调用成功则返回0。WSAStartup()函数调用不成功时返回如下的错误信息:WSASYSNOTREADY:在Winsock的头文件Winsock2.h中,该错误代码定义的数值为10091,它表明加载的Winsock DLL不存在或底层的网络子系统无法使用。,WSAVERNOTSUPPORTED:该代码的数值为10092,所需的Windows Sockets API的版本未由特定的Windows Sockets实现提供。如果由wVersion返回的版本用户不能接受,则要调用WSACleanup()函数清除对Winsock的加载。WSAEINVAL:该代码的数值为10022,说明应用程序指出的Windows Sockets版本不能被该Winsock DLL的实现所支持。WSAEINPROGRESS:该代码的数值为10036,说明一个阻塞的Winsock调用正在进行中。WSAEPROCLIM:该代码的数值为10067,说明已经达到了Windows Sockets实现所支持的任务数量的极限。,WSAEFAULT:该代码数值为10014,说明lpWSAData参数是一个无效的指针。注意:在这里为了便于大家理解错误代码,列出了给错误代码定义的数值。以后为了节省篇幅,不再列出错误代码的数值。如果要查询对应错误代码对应的数值,可以在Winsock的头文件Winsock.h或Winsock2.h中去查找。,4函数使用说明如果用户在没有正确加载Winsock DLL的情况下使用了其他的Winsock API函数,则被调用的函数返回WSANOTINITIALISED错误信息,代码为10093。该函数在程序中的基本使用方法如下:,#include/其他代码WORD wVersionRequested;WSADATA wsaData;wVersionRequested=MAKEWORD(2,2);if(WSAStartup(wVersionRequested,&wasData)!=0),/Winsock初始化错误/输出Winsock初始化错误提示信息,如“WSAStartup failed”return;/下面可以用两种方法中的任一种进行版本号匹配的检查/if(LOBYTE(wsaData.wVersion)!=2|HIBYTE(wsaData.wVersion)!=0)if(wsaData.wVersion!=wVersionRequested),/Winsock版本号不匹配/输出Winsock版本号不匹配的错误提示信息;WSACleanup();return;/说明Winsock DLL的加载正确,可以执行以下的其他代码/其他程序代码结束对Winsock DLL库的使用时,一定要调用WSACleanup()函数卸载所加载的库。,#include void main(void)WSADATA wsaData;/初始化 Winsock 版本 2.2 if(Ret=WSAStartup(MAKEWORD(2,2),Winsock应用程序框架,6.4.2 创建套接口socket()或WSASocket()应用程序在使用套接口通信前,必须要拥有一个套接口。使用socket()或WSASocket()函数来给应用程序创建一个套接口1函数格式 在Winsock 1中提供的创建套接口函数的格式如下:SOCKET socket(int af,int type,int protocol);,在Winsock 2中提供的该函数的扩展格式如下:SOCKET WSASocket(int af,int type,int protocol,LPWSAPROTOCOL_INFO lpProtocolInfo,Group g,int iFlags);,2函数参数说明以上两种格式中,前面三个参数的含义是一样的,说明如下:af:该参数说明套接口要使用的协议地址族,地址族与协议族的含义相同。如果想建立一个UDP或TCP套接口,只能用常量AF_INET表示使用互联网协议(IP)地址。当然,Winsock 2还支持其他的协议,但一般在程序中很少使用。type:该参数描述套接口的协议类型。当第一个参数af是AF_INET时,它只能使用SOCK_STREAM、SOCK_DGRAM或SOCK_RAW三个协议类型中的任一个,分别表示要创建的是流式套接口、数据报套接口或原始套接口。,protocol:该参数说明该套接口使用的特定协议。当协议地址族af和协议类型type已经确定后,协议字段可以使用的值是限定的,如表6-1所示。如果调用者不希望特别指定所使用的协议,可以将此参数设置为0,系统就根据前两个参数的值自动确定一个协议字段的取值。以上三个参数就可以确定一个套接口,它们之间的对应关系可以用表6-1表示。,表6-1 套接口参数,系统可以根据这三个参数建立一个套接口,并给它分配相应的资源,同时返回一个整型套接口号。因此,socket()函数调用实际上指定了相关五元组中的“协议”这一元。使用Winsock 2时,一般可以先用WSAEnumProtocols()函数(该函数在第8章介绍),以获得系统所安装协议的相关信息。当然对现在的绝大部分用户来说,直接使用AF_INET(IP协议族)就可以了,因为几乎所有的协议实现系统都支持IP协议族。但要编写通用性好的应用程序时,最好还是先使用WSAEnumProtocols()函数查询一下系统安装的协议。,在Winsock 2提供的扩展格式中,增加了三个参数,其含义说明如下(因为常用的是格式1,所以这三个参数只需了解其大概的含义):lpProtocolInfo:一个指向WSAPROTOCOL_INFO结构的指针,该结构定义所创建套接口的特性。如果本参数不指向空(NULL),则前三个参数(af,type,protocol)被忽略,系统就根据该结构中三个字段的值确定套接口类型。g:套接口组的描述字。组参数始终为0,因为目前尚无可支持套接口组的Winsock版本。,iFlags:套接口属性描述。iFlags可用参数如下:WSA_FLAG_OVERLAPPEDWSA_FLAG_MULTIPOINT_C_ROOTWSA_FLAG_MULTIPOINT_C_LEAFWSA_FLAG_MULTIPOINT_C_ROOFWSA_FLAG_MULTIPOINT_D_LEAF,第一个标志WSA_FLAG_OVERLAPPED用于指定这个套接口具备重叠I/O(是适用于Winsock的通信模式之一)的特性。调用socket()建立一个套接字时,WSA_FLAG_OVERLAPPED便是默认设置。一般说来,在使用WSASocket时,最好始终保持设定该标志。后面4个标志用于处理多播套接口。3函数返回信息该函数调用成功后,返回新创建的套接口号,它被定义成是一个无符号的整型数据。函数调用错误时返回INVALID_SOCKET,应用程序可进一步调用WSAGetLastError()函数来获取相应的错误代码。可能获得的错误代码说明如下:,WSANOTINITIALISED:在调用本API之前应成功调用WSAStartup();WSAENETDOWN:网络子系统失效;WSAEAFNOSUPPORT:不支持指定的地址族;WSAEINPROGRESS:一个阻塞的Winsock调用正在进行中,或者服务提供者仍在处理一个回调函数;WSAEMFILE:无可用的套接口描述字;WSAENOBUFS:无可用的缓冲区空间,套接口无法创建;,WSAEPROTONOSUPPORT:不支持指定的协议;WSAEPROTOTYPE:指定的协议对于本套接口类型错误;WSAESOCKTNOSUPPORT:本地址族不支持指定的套接口类型;WSAEINVAL:g参数非法。,4函数使用说明 要创建一个流套接口时,可以使用下列三种格式之一:SOCKET sockid=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);SOCKET sockid=WSASocket(AF_INET,SOCK_STREAM,0);SOCKET sockid=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);,要创建一个数据报套接口时,其格式如下(为节省篇幅,两种套接口的创建只给出了一种格式):SOCKET sockid=socket(AF_INET,SOCK_GDRAM,IPPROTO_UDP);要创建一个原始套接口时,其格式如下:SOCKET sockid=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);,6.4.3 指定本地地址bind()当用socket()创建了一个套接口后,该套接口还是不能直接使用,因为它只存在于一个名字空间(地址族)中,也就是说它只确定了通信所希望使用的服务类型,并没有与该主机上提供服务的某端口联系在一起,这样的套接口可以叫未命名的套接口。bind()函数通过给一个未命名的套接口分配一个本地名字来为套接口建立本地捆绑,即把一个套接口与一个主机地址和端口号联系起来。本函数适用于数据报或流类套接口。,1函数格式bind()函数的格式如下:int bind(SOCKET s,const struct sockaddr FAR*name,int namelen);,2函数参数说明bind()函数中各参数的说明如下:s:标识一未绑定套接口的描述字,它是socket()函数调用成功时返回的值。name:是一个与指定协议有关的地址结构指针,它指向的值是赋予套接口的地址信息。在Winsock中使用sockaddr_in结构指定IP地址和端口信息,它的定义如下:struct sockaddr_inshort sin_family;u_short sin_port;struct in_addrsin_addr;charsin_zero8;,sin_family字段必须为AF_INET,以告诉Winsock所使用的是IP地址族;sin_port是以网络字节顺序表示的16位端口号;sin_addr是以网络字节顺序表示的32位IP地址;sin_zero字段不用,一般用0填充,在程序中通常是使用sockaddr_in之前将整个结构置0。namelen:bind()函数的这个参数指地址参数(name)的长度。,3函数返回信息如果调用没有错误发生,则bind()返回0,否则将返回SOCKET_ERROR,应用程序可进一步通过WSAGetLastError()函数来获取相应的错误代码。下面是可能获取的错误代码:WSANOTINITIALISED:在使用此API之前应首先成功调用WSAStartup();WSAENETDOWN:Windows套接口实现检测到网络子系统失效;,WSAEADDRINUSE:所指定的端口已在使用中;WSAEFAULT:namelen参数太小(小于sockaddr结构的大小);WSAEINPROGRESS:一个阻塞的Windows套接口调用正在运行中;WSAEAFNOSUPPORT:本协议不支持所指定的地址族;WSAEINVAL:该套接口已与一个地址捆绑;WSAENOBUFS:无足够可用缓冲区,连接过多;WSAENOTSOCK:指定的描述字不是一个套接口。,4函数使用说明各种IP地址和端口的设置可用表6-2表示。,表6-2 IP地址和端口的几种设置方式,在程序中使用bind()调用的典型方式如下所示:#include SOCKET s;sockaddr_in tcpaddr;int iSockErr;int port=5000;/端口号/先创建一个使用IP地址族的流式套接口s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);,/以下给结构类型的地址提供数值tcpaddr.sin_family=AF_INET;/htons()函数把一个16位主机字节顺序的端口号转化为网络字节顺序tcpaddr.sin_port=htons(port);/htons()函数把一个32位主机字节顺序的IP地址转化为网络字节顺序=htonl(INADDR_ANY);/=”);,struct sockaddr u_short sa_family;char sa_data14;struct in_addr union struct u_char s_b1,s_b2,s_b3,s_b4;S_un_b;struct u_short s_w1,s_w2;S_un_w;u_long S_addr;S_un;,几个结构:,if(bind(s,(LPSOCKADDR)/函数调用成功,进行其他处理,该程序段是使用bind()调用常用的形式,由内核指定IP地址,应用程序指定端口号。至此,通信过程中一端的协议、地址和所使用的端口号已经确定,一个套接口就可以正常使用了,即可以进行数据的接收或发送操作了。,6.4.4 监听连接listen()在一个服务器端用socket()调用成功创建了一个套接口,并用bind()函数和一个指定的地址关联(即绑定)在一起后,要指示该套接口进入监听连接请求的状态以及接收由客户发出的连接请求,就要用到Winsock API函数listen()。1函数格式int listen(SOCKET s,int backlog);,2函数参数说明listen()函数中各参数说明如下:s:用于标识一个已绑定了地址,但还未建立连接的套接口描述字。backlog:该参数指定了正在等待连接的最大队列长度。这个参数非常重要,因为完全可能同时出现几个对服务器的连接请求。例如,假定backlog参数为2时有三个客户机同时发出连接请求,那么前两个会被放在一个“等待处理”队列中,以便应用程序依次为它们提供服务。,第三个连接的请求会造成一个WSAECONNREFUSED错误。一旦服务器接受了一个连接请求,那个连接请求就会从队列中删去,以便可以继续接收其他客户发出的连接请求。要注意的是,backlog参数本身的大小就存在着限制(SOMAXCONN),这个限制是由协议提供者决定的。3函数返回信息如果listen()函数的调用无错误发生,则返回值为0,否则返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应的错误代码。下面是可能获得的错误代码的说明:,WSANOTINITIALISED:在使用此API之前应成功调用WSAStartup();WSAENETDOWN:Windows套接口实现检测到网络子系统失效;WSAEADDRINUSE:试图用listen()去监听一个正在使用中的地址;WSAEINPROGRESS:一个阻塞的Windows套接口调用正在运行中;WSAEINVAL:该套接口未用bind()进行捆绑,或已被连接;,WSAEISCONN:套接口已被连接;WSAEMFILE:无可用文件描述字;WSAENOBUFS:无可用缓冲区空间;WSAENOTSOCK:描述字不是一个套接口WSAEOPNOTSUPP:该套接口不能正常支持对listen()的调用。4函数使用说明listen()仅适用于支持连接的套接口,如SOCK_STREAM类型的套接口。也就是说,在IP地址族中,它只适用于同时有多个连接请求的TCP服务器。如果当一个连接请求到来时队列已满,那么客户将收到一个WSAECONNREFUSED错误。,6.4.5 请求连接connect()或WSAConnect()当服务器端建立好套接口并与一个本地地址绑定后,就进入监听状态,等待客户发出连接请求,从而为客户提供服务。在客户端当套接口建立好之后,就要调用connect()函数,提出与一个服务器建立连接的请求,如果服务器接受请求,就可以在服务器的远程套接口与客户端的本地套接口之间建立一条连

    注意事项

    本文(网络程序设计基本知识.ppt)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开