书签 分享 收藏 举报 版权申诉 / 106
上传文档赚钱

类型通信网络程序设计章-课件5.ppt

  • 上传人(卖家):ziliao2023
  • 文档编号:7267278
  • 上传时间:2023-11-08
  • 格式:PPT
  • 页数:106
  • 大小:577.50KB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《通信网络程序设计章-课件5.ppt》由用户(ziliao2023)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    通信 网络程序设计 课件
    资源描述:

    1、1 1第5章 IPX/SPX网络编程5.1 概述概述5.2 套接字套接字5.3 IPX/SPX协议结构协议结构5.4 IPX程序设计程序设计5.5 SPX程序设计程序设计小结小结2 2Internet分组交换/顺序分组交换协议(即IPX/SPX协议)是Novell公司为了适应网络的发展而开发的通信协议,具有很强的适应性,且安装方便,同时还具有路由功能,可以实现多网段间的通信,是一种早期的网络通信协议。IPX/SPX协议是三大协议中重要的一种,虽然已经渐渐淡出历史舞台,但是对其编程思想的学习有利于对后续TCP/IP学习思维的形成。本章从IPX/SPX的概念入手,介绍套接字编程接口及IPX/SPX

    2、协议结构,最后,结合实践对IPX/SPX的编程方法进行了介绍。3 3IPX/SPX是IPX与SPX协议的组合,IPX协议负责数据包的传送;SPX负责数据包传输的完整性。在微软的NT操作系统中,一般使用NWLink IPX/SPX兼容协议和NWLink NetBIOS两种IPX/SPX的兼容协议,即NWLink协议,该兼容协议继承了IPX/SPX协议的优点,更适应Windows的网络环境。5.1 概概 述述4 4IPX/SPX协议一般可以应用于大型网络(比如Novell)和局域网游戏环境中(比如反恐精英、星际争霸)。不过,如果不是在Novell网络环境中,一般不使用IPX/SPX协议,而是使用I

    3、PX/SPX兼容协议,尤其是在Windows 9x/2000组成的对等网中。5 5IPX是互联网分组交换协议(Internetwork Packet Exchange Protocol)的简称,是 Novell NetWare 操作系统所支持的互联网络中路由数据包的早期网络协议。IPX是一种面向无连接通信的数据报协议,类似于TCP/IP协议组中的网际协议(即IP),其高层协议,如SPX和NCP,主要提供差错恢复服务。在局域网中传输数据包时,如果接收节点在同一网段内,则通过IPX协议就直接按该节点的ID将数据传给报收节点;如果接收节点不在同一网段内,那么通过IPX协议可以将数据包交给NetWar

    4、e服务器,再继续传输。6 6为了选择最佳路径,IPX使用动态距离矢量(distance vector)路由选择协议,如路由信息协议(Routing Information Protocol,RIP)或链路状态协议(NetWare Link-State Protocol,NLSP)。SPX是顺序包交换协议(Sequences Packet Exchange Protocol)的简称,是基于施乐的Xerox SPP(Sequences Packet Protocol,顺序包协议)协议提出的,同样是由Novell公司开发的一种用于局域网的网络协议。在局域网中,SPX协议主要负责对整个传输的数据进行无

    5、差错处理,即纠错。SPX协议一般和上面介绍的IPX协议组合成IPX/SPX协议来使用,多用于Netware网络环境以及联网游戏。7 7如前所述,在本书Windows操作系统中实现IPX/SPX协议编程要使用IPX/SPX兼容协议(NWLink IPX/SPX/NetBIOS Compatible Transport Protocol),此外,该协议是通过套接字(Socket)调用实现的。Socket是一种通用叫法,在Windows操作系统下,微软对Socket的封装就是WinSock。5.2 套套 接接 字字8 85.2.1 5.2.1 基本概念基本概念1 1套接字的概念套接字的概念从网络程序

    6、设计的角度来说,套接字就是一个指向传输提供者的句柄。在以太网网络通信环境下,套接字数据传输是一种特殊的I/O,它也相当于一种文件描述符,用一个类似于打开文件的函数Socket()。调用Socket()可以这样理解:建立了一个通信端点,通过它,用户的套接字程序可以通过网络和其他的套接字应用程序通信。套接字存在于一个“通信域”(为描述一般的线程如何通过套接字进行通信而引入的一种抽象概念)里,并且与另一个域的套接字交换数据。9 9Windows Sockets规范简称WinSock,是一套开放的、支持多协议的Windows下的网络编程接口,在Intel、Microsoft、Sun、SGI、Infor

    7、mix、Novell等公司的全力支持下,已经成为Windows网络编程的事实上的标准。Windows Sockets API是Microsoft Windows的网络程序接口,它包括一个标准的Berkeley Sockets功能调用的集合,以及为Windows所做的重要扩充。扩充的功能调用都用WSA(Windows Sockets Asynchronous)作前缀,表明它们允许异步的I/O操作,并采用了符合Windows消息机制的网络事件异步选择机制。这些扩充有利于应用程序开发者更好地利用Windows的消息驱动特性,设计出高性能的网络程序。1010WinSock的实现一般都由两部分组成:开发

    8、组件和运行组件。开发组件是供程序员开发Windows Sockets应用程序使用的,包括介绍WinSock实现的文档、WinSock应用程序接口(API)引入库和一些头文件。WinSock最重要的头文件就是WinSock.h(或WinSock2.h),它包括了WinSock实现所定义的宏、常数值、数据结构和函数调用接口原型。运行组件是WinSock应用程序接口的动态连接库(.dll),文件名为WinSock.dll(对于32位机的WinSock2而言还有WS2_32.dll,它是通过将WS2_32.lib加入编译器中的工程的,否则需要动态载入WS2_32.dll,加载方法见9.3.2节),应用

    9、程序在执行时通过装入它来实现网络通信功能。11112 2协议支持协议支持WinSock编程接口是一个与协议无关的接口,在Win32平台下支持许多种通信协议,如IPX/SPX、NetBIOS、TCP/IP、AppleTalk、ATM、红外线套接字(Windows CE下的WinSock只支持TCP/IP协议)等,并且还可以扩展。不管使用哪一种协议,它们的操作基本是类似的。虽然WinSock不是一种网络协议(其本身与协议无关),但是它可以访问很多种网络协议。可以把它当作一些协议的封装,使用WinSock来调用多种协议的功能。1212通过调用WinSock的接口函数来调用操作系统提供的协议。例如:若

    10、是基于IPX/SPX协议发送数据,就可以通过创建一个封装IPX/SPX协议的套接字,然后使用WinSock的接口函数Send()调用IPX/SPX的发送数据功能,这步工作在WinSock2中由服务提供者接口(Service Provider Interface,SPI)实现(详见9.4.2节)。对照表5-1中的Windows实现OSI七层模型对应的文件类型及文件实例示意,即能够理解只要绑定不同的协议驱动文件,就可以实现WinSock对多种通信协议的调用。1313表5-1 WinSock网络编程OSI各层的实现1414不同协议的.sys文件(如tcpip.sys、netbios.sys、nwln

    11、kipx.sys等)都可以在Windows系统文件夹C:WINDOWSsystem32drivers中找到。要想获得系统中安装的网络协议的相关信息,还可以通过调用WSAENumProtocols函数来实现,其原型为int WSAENumProtocols(LPINT lpiProtocols,/协议标识号数组LPWSAPROTOCOL_INFO lpProtocolBuffer,/缓冲区LPDWORD lpdwBufferLength);/lpProtocolBuffer缓冲区长度其中,参数lpiProtocols是一个以NULL结尾的协议标识号数组,该参数可选。1515如果lpiProtoc

    12、ols为NULL,则返回所有可用协议的信息;否则返回数组中所列的协议信息。参数lpProtocolBuffer是一个用PROTOCOL_INFO结构填充的缓冲区,该结构用来存取和获得给定协议的完整信息。参数lpdwBufferLength在输入时,用于保存传递给WSAENumProtocols()函数的lpProtocolBuffer缓冲区长度;在输出时,存有获取所有请求信息需传递给WSAENumProtocols()函数的最小缓冲区长度。PROTOCOL_INFO的结构如下:typedef struct _WSAPROTOCOL_INFO1616DWORDdwServiceFlags1;/描

    13、述协议提供的服务的位掩码DWORDdwServiceFlags2;/保留为另外的协议属性定义DWORDdwServiceFlags3;/保留为另外的协议属性定义DWORDdwServiceFlags4;/保留为另外的协议属性定义DWORDdwServiceFlags5;/提供协议在协议目录中如何表示的信息1717GUIDProviderId;/供应商给服务提供者赋予的全局唯一标识DWORDdwCatalogEntryId;/WS_32.dll对WSAPROTOCOL_INFO结构的唯一标识WSAPROTOCOLCHAINProtocolChain;/一个包含构成协议链的目录入口号计数列的结构i

    14、ntiVersion;/协议版本标识符intiAddressFamily;/作为地址族参数传递给socket()/WSAsocket()函数,/以便为此协议打开一个套接字,此值也唯一地定义了/使协议用的协议地址结构1818intiMaxSockAddr;/最大的地址长度,单位为B(字节)intiMinSockAddr;/最小的地址长度,单位为B(字节)intiSocketType;/作为类型参数传递给socket()函数intiProtocol;/作为协议参数传递给socket()函数intiProtocolMaxOffset;/最大协议偏移值intiNetworkByteOrder;/网络字

    15、节顺序1919intiSecurityScheme;/指示使用的安全方案类型DWORDdwMessageSize;/协议支持的最大消息长度DWORDdwProviderReserved;/为服务提供者保留TCHARszProtocolWSAPROTOCOL_LEN+1;/标识此协议的字符串,如“SPX”WSAPROTOCOL_INFO,*LPWSAPROTOCOL_INFO;2020通常需要调用WSAENumProtocols()函数两次以获取特定的协议信息。第一次调用时,指定lpProtocolBuffer()为NULL,调用失败,返回WSAENOBUFS错误,但参数lpdwBufferLe

    16、ngth包含了所有协议信息需要的缓冲区长度。分配了恰当的缓冲区长度后,便可利用这个缓冲区进行第二次调用了,协议的信息将包含在WSAPROTOCOL_INFO结构中。这样,就可以对该结构进行分析,从而获得所需要的协议信息了。21213 3使用方式使用方式在VC中进行WinSock的API编程开发,需要使用到下面三个文件:(1)Winsock.h:这是WinSock API的头文件。(2)WSock32.lib:WinSock API链接库文件。在使用中,一定要把它作为项目的非缺省的链接库而包含到项目文件中去。(3)WinSock.dll:WinSock的动态链接库,位于Windows的安装目录下

    17、。Winsock.dll位于通信协议栈和应用程序之间,即WinSock管理与通信协议的接口。22224 4创建与关闭创建与关闭可以选择使用socket或WSAsocket函数之一来建立一个套接字,它们主要完成的功能是给指定的地址族、数据类型和协议分配一个套接字描述符以及相关的资源。根据这三个参数(WSAsocket以及其他辅助参数)建立一个套接字,并将相应的资源分配给它,同时返回一个整型套接字号,实际上指定了全相关五元组(1.3.3节)中的“协议”这一元。socket的原型函数如下:SOCKET WSAAPI socket(int af,int type,int protocol);其中:23

    18、23af:是一种地址格式描述,代表不同网络的寻址方法,可以是AF_INET、AF_IPX、AF_NETBIOS、AF_APPLETALK、AF_ATM、AF_IRDA、AF_UNIX中的一种,分别代表不同的寻址方式。这个参数对后面的套接字类型有影响,例如使用AF_ATM时,套接字的类型只有原始套接字类型。type:描述要建立的套接字的类型,可以有五种选择:SOCK_STREAM、SOCK_2424DGRAM、SOCK_SEQPACKET、SOCK_RDM和SOCK_RAW,分别标识流式、数据报式、定序分组式、可信赖数据包连接式和原始套接字。在各种协议下,对五种类型的支持不完全相同。protoc

    19、ol:说明该套接字使用的特定协议,如果调用者不希望特别指定使用的协议,则置为0,即使用默认的连接模式。如果没有错误产生,socket()函数返回一个与建立的套接字相关的描述符;否则,返回INVALID_SOCKET。2525套接字使用完后需关闭,可使用closesocket()函数。closesocket()函数关闭套接字s,并释放分配给该套接字的资源。如果s涉及一个打开的TCP链接,则该链接被释放。closesocket()的原型函数如下:int WSAAPI closesocket(SOCKET s);其中,s是待关闭的套接字的描述符。返回值为:如果没有错误产生,closesocket()

    20、返回0;否则,返回SOCKET_ERROR。除了closesocket()函数外,shutdown()函数也可以暂停一个Socket。26265 5使用过程使用过程总的来说,使用套接字接口(面向连接或无连接)进行网络通信时,必须按下面四步进行处理:(1)程序必须建立一个Socket。(2)程序必须按要求配置此Socket。也就是说,程序或者将此Socket连接到远方的主机上建立全相关,或者给此Socket指定一个本地协议端口,建立半相关。(3)程序需按要求通过此Socket发送和接收数据。(4)通信完毕后,程序必须关闭此Socket。在通信过程中,还可以对该套接字的I/O进行管理(详见6.6节

    21、),以实现更加复杂的应用。27275.2.2 WinSock5.2.2 WinSock的启动与终止的启动与终止WinSock是一种服务,这种服务在使用前要启动,使用后要终止。1 1WinSockWinSock的启动的启动由于WinSock的服务是以动态链接库WinSock dll形式实现的,因此必须先调用WSAStartup()函数对WinSock dll进行初始化,协商WinSock的版本支持,并分配必要的资源。如果在调用WinSock()函数之前,没有加载WinSock库,则返回SOCKET_ERROR错误,错误信息是WSANOTINITIALISED。启动套接字服务的WSAStartup

    22、函数原型如下:2828int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);其中:参数wVersionRequested为调用者可以使用的Windows Sockets API支持的最高版本号。参数lpWSAData指向接收Windows Sockets实现细节的数据结构WSADATA的指针。返回值是:如果调用成功,返回0;否则,返回错误码。此函数初始化WinSock dll时,必须被应用程序或dll第一个调用的Windows Sockets()函数所允许。2929应用程序或dll指定Windows Sockets API要求的版

    23、本,以获取指定的Windows Sockets()实现的细节。应用程序或dll只有在一次成功的WSAStartup()执行后才能发布后续的WinSock()函数。30302 2WinSockWinSock的终止的终止在应用程序关闭套接字后,还应调用WSACleanup()函数终止对WinSock dll的使用,并释放资源,以备下一次使用。WSACleanup函数的原型如下:int WSACleanup(void);该函数不带任何参数,若调用成功则返回0,否则返回错误。31315.2.3 WinSock5.2.3 WinSock的主要函数的主要函数WinSock虽然封装了各种协议,但各种通信协议

    24、的主要操作函数基本一致,下面进行简要介绍。1 1连接函数连接函数连接函数:accept()、bind()、connect()。accept()函数用于面向连接服务器。bind()函数用于未连接的数据报或流套接字,将一个本地地址与套接字相连接,即建立半相关。connect()函数用于与对等方建立一个连接。如果套接字s没有绑定,则系统赋予本地相关的唯一值,并且将套接字表示为已绑定的。32322 2传输函数传输函数传输函数:recv()、recvfrom()、send()、sendto()。recv()函数用于在参数s指定的已连接的数据报或流套接字上读取输入数据。recvfrom()函数用于在参数s

    25、指定的套接字(可能已连接)上读取输入数据,并捕获发送数据的地址,存入源地址缓冲区。send()函数用于在参数s指定的已连接的数据报或流套接字上发送输出数据。sendto()函数用于在参数s指定的数据报或流套接字上向指定的目的地址发送输出数据。33333 3I/OI/O函数函数WinSock提供了一系列套接字I/O控制函数控制套接字的I/O行为,并获取套接字I/O操作的有关信息。其中最常用的是ioctlsocket()函数,它可用于任一状态的任一套接字,而与具体协议或通信子系统无关。其原型为int ioctlsocket(SOCKET s,long cmd,u_long FAR*argp);其中

    26、:参数s是一个标识套接字的描述字。参数cmd用于指定对套接字s的操作命令,标准的I/O控制命令如表5-2所示。3434除了上述标准I/O控制命令外,WinSock2还提供其他一些控制命令,以及安全套接字层、ATM I/O控制命令等,这里就不做过多介绍了。需要特别掌握的是WinSock2的SIO_RECVALL命令,它可以将网卡设置成混杂模式,通过被设置的原始套接字接收网络中所有的数据包。与ioctlsocket()功能类似的函数还有WSAIoctl(),它提供了更多的命令选项,可参考MSDN中的有关说明。3535表5-2 标准的I/O控制命令36364 4套接字选项函数套接字选项函数套接字建立

    27、后,可通过套接字选项函数获得与设置套接字相关的信息。这样的函数有两个,即getsockopt()和setsockopt(),二者的结构非常相似,下面进行联合讲解。getsockopt()函数可以获得套接字选项,它的常见用法是获得与指定套接字相关的信息,其原型为int getsockopt(SOCKET s,int level,int optname,char FAR*optval,int FAR*optlen);setsockopt()函数可以设置套接字选项,它的常见用法是设置与指定套接字相关的信息,其原型为3737int setsockopt(SOCKET s,int level,int o

    28、ptname,const char FAR*optval,int optlen);其中:参数s是一个标识套接字的描述字。参数level用于指定套接字选项的级别,大多数选项都是一种特定的协议和套接字类型专有的,而其他选项适用于所有类型的套接字。参数optname表示需要设置的选项。参数optval为指向存放选项值缓冲区的指针。参数optlen为optval缓冲区的长度。getsockopt()和setsockopt()的optval和optlen的形式稍有区别,在getsockopt()函数中将它们的值传出,而在setsockopt()函数中将它们的值传入。3838套接字的相关信息众多,是要获得

    29、还是设置哪一个选项,则必须使用level和optname两个参数指明。level和optname的取值有严格的对应关系,请参考附录6。下面函数可设置原始套接字(详见7.3.1节)的IP包的TTL值,是后面实现tracert程序的关键。setsockopt(s,IPPROTO_IP,IP_TTL,(char*)&nValue,sizeof(nValue);39395 5错误检查和控制错误检查和控制错误检查和控制对于WinSock应用程序是至关重要的。事实上,对WinSock API函数来说,返回错误是很常见的,但多数情况下,通信仍可在套接字上进行。尽管返回的值并非一成不变,但不成功的WinSoc

    30、k调用返回的最常见的值是SOCKET_ERROR。SOCKET_ERROR是值为-1的常量。如果返回了错误,则可用WSAGetLastError()(或GetLastError()函数获得一段代码,这段代码明确表明产生错误的原因。WSAGetLastError()函数的原型如下:4040int WSAAPI WSAGetLastError(void);函数返回值指示当前线程最近执行的Windows Sockets API()函数产生的错误,可以在附录3中进行查阅,了解出错原因,也可以使用编译器提供的“Error Lookup”工具查询出错原因。4141本节介绍使用WinSock实现IPX/SP

    31、X编程的方法。5.3.1 IPX5.3.1 IPX协议结构协议结构IPX是Novell 公司最基本的通信协议。在NetWare环境下,工作站、服务器和网桥之间的通信都建立在以IPX为基础的IPX协议上,即网间数据包交换协议,其作用是帮助一个数据包选择路径、交换寻址,并将它送到目的地。因此,在ISO的开放互连(OSI)模型中,IPX协议处于网络层的位置,它也被称做是一种无连接的数据包规程。5.3 IPX/SPX协议结构协议结构4242IPX协议具有以下三个特点:采用IPX协议通信的双方不用事先建立连接,因而通信速度快、效率高。虽然Netware不能保证数据一定能够到达目标地址,但可以保证IPX发

    32、送成功率达95%。因为IPX协议具有CRC的校验功能,可以保证数据包本身的正确性。如果接收方在规定的时限内不响应,IPX将会自动重发。IPX路由信息全部包括在数据包中,因此IPX包路由选择灵活,可方便地向多个工作站进行广播。IPX协议下的数据传输采用固定结构、可变长的数据包。一个IPX协议数据包包含地址、路由、数据等字段信息,其结构如表5-3所示。4343表5-3 IPX协议数据包结构4444下面对表5-3中的几个关键字段进行进一步介绍。(1)数据包类型,即数据包第5个字节,代表这个IPX数据包所传输的种类,类型取值可以是表5-4中所定义的类型。4545表5-4 IPX数据包的类型4646(2

    33、)目标地址部分,即数据包第617个字节,这部分用于说明IPX数据包发往何方,目标地址组成:目标网络地址+目标节点地址+目标套接口地址。(3)源地址部分,即数据包第1829个字节,源地址部分用于说明IPX数据包从何处发出,源地址组成:源网络地址+源节点地址+源套接口地址。(4)数据,即数据包第30个字节。IPX数据包的数据部分通过IPX数据包所传送的数据存放在IPX数据从结构第30个字节起的单元内,数据长度不超过547个字节。47475.3.2 5.3.2 协议地址协议地址1 1地址结构地址结构要用IPX进行WinSock客户机或服务器通信,必须使用结构为SOCKADDR_IPX的地址。在wsi

    34、px.h文件中规定了IPX/SPX协议地址结构SOCKADDR_IPX如下:typedef struct sockaddr_ipx shortsa_family;charsa_netnum4;charsa_nodenum6;unsigned short sa_socket;SOCKADDR_IPX,*PSOCKADDR_IPX,FAR*LPSOCKADDR_IPX;4848其中,sa_family字段应设为AF_IPX值;sa_netnum字段是4字节的地址,代表IPX网络上的网段号;sa_nodenum字段是6字节的地址,代表节点计算机的物理地址;sa_socket字段代表一个节点区分IPX

    35、通信的套接字或接口。Novell IPX 网络地址是唯一的,以十六进制表示。它由两部分组成:网络号和节点号。IPX网络号由网络管理员分配,地址长32位;节点号通常是系统网络接口卡(NIC)的介质访问控制(MAC)地址,地址长48位。通过MAC地址作为节点号,系统可以通过发送节点以判断数据链路使用的MAC地址。4949如果节点地址为0 xFFFFFFFFFFFF(六个字节全为0 xFF),则该数据包以广播方式发往网络上的所有节点工作站。IPX的用户套接字号为4000HFFFFH,由NetWare SHELL动态分配。IPX数据包数据部分的长最小为30个字节(只有头部分),最大值不定,这主要取决于

    36、使用的低层MAC协议(以太网或令牌环)。50502 2地址转换地址转换由于IPX地址是十六进制数,不适宜键盘输入,因此要进行数据的转换,下面代码提供转换功能。十六进制数转换为ASCII码的代码如下:UCHAR BtoH(char ch)if(ch=0)&(ch=A)&(ch=a)&(ch=f)return(ch-a+0 xA);5151 printf(Illegal characters in IPX address!n);/Illegal values in the IPX address will not be accepted ExitProcess(-1);ASCII码转换为十六进制数

    37、的代码如下:void AtoH(char*szDest,char*szSource,int iCount)while(iCount-)*szDest+=(BtoH(*szSource+)4)+BtoH(*szSource+);return;52523 3本地地址枚举本地地址枚举为了方便编程,还可以对本地IPX地址进行枚举,程序代码如下:#include stdafx.h#include#include#include#include#pragma comment(lib,wsock32.lib)SOCKET sock=INVALID_SOCKET;int CreateIPXSocket()略5

    38、353int main(int argc,char*argv)SOCKADDR_IPX sa_ipx;IPX_ADDRESS_DATA ipx_data;int ret,cb,nAdapters,i=0,j=0;WSADATA wsd;5454 if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)printf(WSAStartup()failed:%dn,GetLastError();return-1;CreateIPXSocket();sa_ipx.sa_family=AF_IPX;5555 ret=bind(sock,(SOCKADDR*)&sa_ipx,sizeof

    39、(SOCKADDR_IPX);if(ret=SOCKET_ERROR)printf(bind()failed:%dn,WSAGetLastError();return 0;/Call getsockopt()see the total number of adapters cb=sizeof(nAdapters);5656 ret=getsockopt(sock,NSPROTO_IPX,IPX_MAX_ADAPTER_NUM,(CHAR*)&nAdapters,&cb);if(ret=SOCKET_ERROR)printf(getsockopt(IPX_MAX_ADAPTER_NUM)fail

    40、ed:%dn,WSAGetLastError();return 0;printf(Total number of adapters-%dn,5757nAdapters);for(i=0;i nAdapters;i+)/Get the address of each adapter memset(&ipx_data,0,sizeof(ipx_data);ipx_data.adapternum=i;cb=sizeof(ipx_data);ret=getsockopt(sock,NSPROTO_IPX,IPX_ADDRESS,(CHAR*)&ipx_data,&cb);if(ret=SOCKET_E

    41、RROR)5858 printf(getsockopt(IPX_ADDRESS)failed:%dn,WSAGetLastError();return 0;/Print each address for(j=0;j 4;j+)printf(%02X,(UCHAR)ipx_numj);/Print the net number printf(.);for(j=0;j 6;j+)printf(%02X,5959(UCHAR)ipx_data.nodenumj);/Print the node number printf(n);return 0;本程序若要获取本地IPX地址,首先要创建一个IPX套接

    42、字;接着,将该套接字绑定(bind)到任意一个AF_IPX类型的地址上;然后通过调用getsockopt()函数分别得到适配器的数量和每个适配器上设置的IPX地址;最后用ASCII码的格式打印出来。60605.3.3 SPX5.3.3 SPX协议结构协议结构SPX是一个面向连接的协议,其格式在IPX之上又增加了12个字节,用于定义SPX的特殊信息,即其前面29个字节的字段含义与IPX完全一样,其结构如表5-5所示。6161表5-5 SPX协议数据包结构6262连接控制SPX使用该字节的高4位,用于控制通过“连接”传输的数据流,存在四种取值,即10H表示对方连接结束,20H表示保留,40H表示要

    43、求确认的包,80H表示本包为系统包。数据流类型用于指示SPX数据包中的数据类型或数据作用,可能的取值分三种情况,即取值0FDH表示由客户程序自定义的数据类型;取值FEH表示当客户程序结束一个有效连接时,SPX产生“连接结束”标志,并将本包发送往对方;取值FFH表示SPX自动产生“连接响应结束”标志,但不发往对方。6363IPX程序是非面向连接的,与NetBIOS的数据报类似,这里将IPX的收发集成到一个程序中。5.4 IPX程序设计程序设计64645.4.1 IPX5.4.1 IPX套接字创建套接字创建IPX封装的套接字采用如下方法进行创建,代码如下:int CreateIPXSocket()

    44、sock=socket(AF_IPX,SOCK_DGRAM,NSPROTO_IPX);if(sock=INVALID_SOCKET)printf(socket()failed:%dn,WSAGetLastError();return 0;6565return 1;IPX是一种非面向连接的通信方式,因此其类型只有SOCK_DGRAM一种。66665.4.2 IPX5.4.2 IPX数据收发数据收发下面程序演示了IPX数据接收与发送的实现过程:#include stdafx.h#include#include#include#include#pragma comment(lib,wsock32.l

    45、ib)#define MAX_DATA_LEN 64000/Global Variables6767SOCKET sock=INVALID_SOCKET;void CreateIPXSocket()略,见5.4.1节/SendDatagram()is generic rotuine to send a datagram to a specifid host.int SendDatagram(SOCKET s,char*pchBuffer,SOCKADDR_IPX*psa)int ret;6868 ret=sendto(s,pchBuffer,strlen(pchBuffer),0,(SOCKA

    46、DDR*)psa,sizeof(SOCKADDR_IPX);if(ret=SOCKET_ERROR)printf(sendto()failed:%dn,WSAGetLastError();return-1;6969 return ret;/ReceiveDatagram()is generic rotuine to receive a datagram from a specifid host.int ReceiveDatagram(SOCKET s,char*pchBuffer,SOCKADDR_IPX*psa,int*pcb)int ret;ret=recvfrom(s,pchBuffer

    47、,MAX_DATA_LEN,0,7070(SOCKADDR*)psa,pcb);if(ret=SOCKET_ERROR)printf(recvfrom()failed:%dn,WSAGetLastError();return-1;return ret;int main(int argc,char*argv)7171 WSADATA wsd;SOCKADDR_IPX sa_ipx_sender;/sender address char chBufferMAX_DATA_LEN;/Data buffer int ret,cb,j;if(WSAStartup(MAKEWORD(2,2),&wsd)!

    48、=0)printf(WSAStartup()failed:%dn,7272GetLastError();return-1;CreateIPXSocket();sa_ipx_sender.sa_family=AF_IPX;ret=bind(sock,(SOCKADDR*)&sa_ipx_sender,sizeof(SOCKADDR_IPX);if(ret=SOCKET_ERROR)printf(bind()failed:%dn,WSAGetLastError();7373 return 0;while(1)cb=sizeof(sa_ipx_sender);printf(Waiting for M

    49、essage comes.n);ret=ReceiveDatagram(sock,chBuffer,&sa_ipx_sender,&cb);if(ret=-1)return 0;7474/Print the contents of received datagram and the senders addressprintf(Message Received from Address-);for(j=0;j4;j+)printf(%02X,(UCHAR)sa_ipx_sender.sa_netnumj);/Print the net numberprintf(.);for(j=0;j%sn,r

    50、et,chBuffer);/Echo the datagram on the bound socket to the clientret=SendDatagram(sock,chBuffer,&sa_ipx_sender);if(ret=-1)return 0;printf(%d bytes of data sentn,ret);7676 closesocket(sock);WSACleanup();return 0;该程序首先对网络中的IPX数据报进行接收,如果接收到IPX报文则打印报文源IPX地址和报文内容;再向源IPX地址发送一个响应报文。IPX数据的接收前,需要将IPX套接字绑定到任意

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:通信网络程序设计章-课件5.ppt
    链接地址:https://www.163wenku.com/p-7267278.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库