CMa°deow 下载 第6章地址家族和名字解析 要通过 Winsock建立通信,必须了解如何利用指定的协议为工作站定址。本章将一一说明 Winsock支持的协议以及各协议如何把一个指定家族的地址解析成网络上一台具体的机器 Winsock2引入了几个新的、与协议无关的函数,它们可和任何一个地址家族一起使用:但是 大多数情况下,各协议家族都有自己的地址解析机制,要么通过一个函数,要么作为一个投 给 getsockopt的选项。本章只讲解各协议组成地址结构时所需的一些基本知识。第10章讨论注 册和名字解析函数,这些函数对特定协议家族服务进行声明(这和简单的名字解析稍有不同)。 关于直接名字解析、服务声明与解析之间的差别,可参见第10章 对已讲过的地址家族来说,我们将进一步探讨如何为网络上的一台机器定址。然后,再 针对各个家族建立套接字。除此以外,还要讨论协议独有的名字解析选项 6.1|P 网际协议( Internet protocol,IP)是一种用于互联网的网络协议,已经广为人知。它可广 泛用于大多数计算机操作系统上,也可用于大多数局域网LAN(比如办公室小型网络)和广 域网wAN(比如说互联网)。从它的设计看来,P是一个无连接的协议,不能保证数据投递万 无一失。两个比它高级的协议(TCP和UDP)用于依赖IP协议的数据通信。 1.1 TCP 面向连接的通信是通过“传输控制协议”( Transmission Control protocol,TCP)来完成的 TCP提供两台计算机之间的可靠无错的数据传输。应用程序利用TCP进行通信时,源和目标之 间会建立一个虚拟连接。这个连接一旦建立,两台计算机之间就可以把数据当作一个双向字 节流进行交换 6.1.2UDP 无连接通信是通过“用户数据报协议”( User Datagram Protocol,UDP)来完成的。UDP 不保障可靠数据的传输,但能够向若干个目标发送数据,接收发自若干个源的数据。简单地 说,如果一个客户机向服务器发送数据,这一数据会立即发出,不管服务器是否已准备接收 数据。如果服务器收到了客户机的数据,它不会确认收到与否。数据传输方法采用的是数据 报 TCP和UDP两者都利用IP来进行数据传输,一般称为TCP/P和UDPP。 Winsock通过 AF INET地址家族为IP通信定址,这个地址家族的定义在 Winsock lh和 Winsock2h中 6.13定址 IP中,计算机都分配有一个IP地址,用一个32位数来表示,正式的称呼是“IPv4地址 客户机需要通过TCP或UDP和服务器通信时,必须指定服务器的PP地址和服务端口号。另外
下载 第6章 地址家族和名字解析 要通过Wi n s o c k建立通信,必须了解如何利用指定的协议为工作站定址。本章将一一说明 Wi n s o c k支持的协议以及各协议如何把一个指定家族的地址解析成网络上一台具体的机器。 Winsock 2引入了几个新的、与协议无关的函数,它们可和任何一个地址家族一起使用;但是 大多数情况下,各协议家族都有自己的地址解析机制,要么通过一个函数,要么作为一个投 给g e t s o c k o p t的选项。本章只讲解各协议组成地址结构时所需的一些基本知识。第 1 0章讨论注 册和名字解析函数,这些函数对特定协议家族服务进行声明(这和简单的名字解析稍有不同)。 关于直接名字解析、服务声明与解析之间的差别,可参见第 1 0章。 对已讲过的地址家族来说,我们将进一步探讨如何为网络上的一台机器定址。然后,再 针对各个家族建立套接字。除此以外,还要讨论协议独有的名字解析选项。 6.1 IP 网际协议(Internet Protocol, IP)是一种用于互联网的网络协议,已经广为人知。它可广 泛用于大多数计算机操作系统上,也可用于大多数局域网 L A N(比如办公室小型网络)和广 域网WA N(比如说互联网)。从它的设计看来,I P是一个无连接的协议,不能保证数据投递万 无一失。两个比它高级的协议( T C P和U D P)用于依赖I P协议的数据通信。 6.1.1 TCP 面向连接的通信是通过“传输控制协议”(Transmission Control Protocol, TCP)来完成的。 T C P提供两台计算机之间的可靠无错的数据传输。应用程序利用 T C P进行通信时,源和目标之 间会建立一个虚拟连接。这个连接一旦建立,两台计算机之间就可以把数据当作一个双向字 节流进行交换。 6.1.2 UDP 无连接通信是通过“用户数据报协议”(User Datagram Protocol, UDP)来完成的。U D P 不保障可靠数据的传输,但能够向若干个目标发送数据,接收发自若干个源的数据。简单地 说,如果一个客户机向服务器发送数据,这一数据会立即发出,不管服务器是否已准备接收 数据。如果服务器收到了客户机的数据,它不会确认收到与否。数据传输方法采用的是数据 报。 T C P和U D P两者都利用 I P来进行数据传输,一般称为 T C P / I P和U D P / I P。Wi n s o c k通过 A F _ I N E T地址家族为I P通信定址,这个地址家族的定义在 Winsock 1.h和Winsock 2.h中。 6.1.3 定址 I P中,计算机都分配有一个 I P地址,用一个 3 2位数来表示,正式的称呼是“ I P v 4地址”。 客户机需要通过T C P或U D P和服务器通信时,必须指定服务器的 I P地址和服务端口号。另外
0a103 服务器打算监听接入客户机请求时,也必须指定一个IP地址和一个端口号。 Winsock中,应用 通过 SOCKADDR IN结构来指定P地址和服务端口信息,该结构的格式如下: struct sockaddr in sin_family sin_port struct in addr sin add sin family字段必须设为 AF INET,以告知 Winsock我们此时正在使用IP地址家族。 P协议第6版 IP协议第6版对原来的IP协议规格进行了改进,将IP地址扩展到16个字节。随着 IPv4 的退场,不久的将来,IPV6的地位显得越来越重要。许多 Winsock头文件中都包含针对 IPv6结构的条件定义:但是当前的win32平台均没有提供IPv6网络堆栈(包括 Windows 2000在内)。“微软研究部”已开发出一个试验性的IPv6堆栈,可从htp:// research microsoft. com/ stripy6/下载;然而,该堆栈未获支持,而且我们不打算深入第6版协议中 专有的特性。 准备使用哪个TCP或UDP通信端口来标识服务器服务这一问题,则由sin_port字段定义 在选择端口时,应用必须特别小心,因为有些可用端口号是为“已知的”(即固定的)服务保 留的(比如说文件传输协议和超文本传输协议,即FTP和HTTP)。“已知的协议”,即固定协 议,采用的端口由“互联网编号分配认证(IANA)”控制和分配,RFC1700中说明编号。从 本质上说,端口号分为下面这三类:“已知”端口、已注册端口、动态和(或)私用端口 ■0~1023由IANA控制,是为固定服务保留的。 ■1024~49151是IANA列出来的、已注册的端口,供普通用户的普通用户进程或程序使 ■49152~65535是动态和(或)私用端口。 普通用户应用应该选择1024-49151之间的已注册端口,从而避免端口号已被另一个应用 或系统服务所用。此外,49152-65535之间的端口可自由使用,因为IANA这些端口上没有注 册服务。在使用 bind Apll函数时,如果一个应用和主机上的另一个应用采用的端口号绑定在 起,系统就会返回 Winsock错误 WSAEADDRINUSE。第7章将深入阐述 Winsock绑定进程」 SOCKADDR IN结构的 sin addr字段用于把一个IP地址保存为一个4字节的数,它是无符 号长整数类型。根据这个字段的不同用法,还可表示一个本地或远程IP地址。IP地址一般是 用“互联网标准点分表示法”(像a.bcd一样)指定的,每个字母代表一个字节数,从左到右 分配一个4字节的无符号长整数。最后一个字段sin_zero,只充当填充项的职责,以使 SOCKADDR IN结构和 SOCKADDR结构的长度一样 个有用的、名为 inet addr的支持函数,可把一个点式IP地址转换成一个32位的无符号 长整数。它的定义如下 unsigned long inet_addr( const char FARcp
第6章计地址家族和名字解析计计103 下载 服务器打算监听接入客户机请求时,也必须指定一个 I P地址和一个端口号。Wi n s o c k中,应用 通过S O C K A D D R _ I N结构来指定I P地址和服务端口信息,该结构的格式如下: s i n _ f a m i l y字段必须设为A F _ I N E T,以告知Wi n s o c k我们此时正在使用I P地址家族。 IP协议第6版 I P协议第6版对原来的 I P协议规格进行了改进,将 I P地址扩展到1 6个字节。随着 I P v 4 的退场,不久的将来, I P v 6的地位显得越来越重要。许多 Wi n s o c k头文件中都包含针对 I P v 6结构的条件定义;但是当前的 Wi n 3 2平台均没有提供 I P v 6网络堆栈(包括 Wi n d o w s 2 0 0 0在内)。“微软研究部”已开发出一个试验性的 I P v 6堆栈,可从 h t t p : / / r e s e a r c h . m i c r o s o f t . c o m / m s t r i p v 6 /下载;然而,该堆栈未获支持,而且我们不打算深入第 6版协议中 专有的特性。 准备使用哪个 T C P或U D P通信端口来标识服务器服务这一问题,则由 s i n _ p o r t字段定义。 在选择端口时,应用必须特别小心,因为有些可用端口号是为“已知的”(即固定的)服务保 留的(比如说文件传输协议和超文本传输协议,即 F T P和H T T P)。“已知的协议”,即固定协 议,采用的端口由“互联网编号分配认证( I A N A)”控制和分配,RFC 1700中说明编号。从 本质上说,端口号分为下面这三类:“已知”端口、已注册端口、动态和(或)私用端口。 ■ 0 ~ 1 0 2 3由I A N A控制,是为固定服务保留的。 ■ 1 0 2 4 ~ 4 9 1 5 1是I A N A列出来的、已注册的端口,供普通用户的普通用户进程或程序使 用。 ■ 4 9 1 5 2 ~ 6 5 5 3 5是动态和(或)私用端口。 普通用户应用应该选择 1 0 2 4 ~ 4 9 1 5 1之间的已注册端口,从而避免端口号已被另一个应用 或系统服务所用。此外, 4 9 1 5 2 ~ 6 5 5 3 5之间的端口可自由使用,因为 I A N A这些端口上没有注 册服务。在使用bind API函数时,如果一个应用和主机上的另一个应用采用的端口号绑定在一 起,系统就会返回Wi n s o c k错误W S A E A D D R I N U S E。第7章将深入阐述Wi n s o c k绑定进程。 S O C K A D D R _ I N结构的s i n _ a d d r字段用于把一个 I P地址保存为一个 4字节的数,它是无符 号长整数类型。根据这个字段的不同用法,还可表示一个本地或远程 I P地址。I P地址一般是 用“互联网标准点分表示法”(像a . b . c . d一样)指定的,每个字母代表一个字节数,从左到右 分配一个 4字节的无符号长整数。最后一个字段 sin_ zero ,只充当填充项的职责,以使 S O C K A D D R _ I N结构和S O C K A D D R结构的长度一样。 一个有用的、名为 i n e t _ a d d r的支持函数,可把一个点式 I P地址转换成一个 3 2位的无符号 长整数。它的定义如下: unsigned long inet_addr( const char FAR *cp );
104第二部分WmkB 下载 cp字段是一个空中止字符串,它认可点式表示法的PP地址。注意,这个函数把IP地址当作 个按网络字节顺序排列的32位无符号长整数返回(网络字节顺序在下面的“字节排序”小 节中简要说明) 1.特殊地址 对于特定情况下的套接字行为,有两个特殊IP地址可对它们产生影响。特殊地址 INADDR ANY允许服务器应用监听主机计算机上面每个网络接口上的客户机活动。一般情况 下,在该地址绑定套接字和本地接口时,网络应用才利用这个地址来监听连接。如果你有 个多址系统,这个地址就允许一个独立应用接受发自多个接口的回应 特殊地址 INADDR BROADCAST用于在一个IP网络中发送广播UDP数据报。要使用这个 特殊地址,需要应用设置套接字选项 SO BROADCAST。第9章将对该选项进行详细论述 2.字节排序 针对“大头”(big- endian)和“小头”( little-endian)形式的编号,不同的计算机处理器 的表示方法有所不同,这由各自的设计决定。比如, Intel86处理器上,用“小头”形式来表 示多字节编号:字节的排序是从最无意义的字节到最有意义的字节。在计算机中把IP地址和 端口号指定成多字节数时,这个数就按“主机字节”(host-byte)顺序来表示。但是,如果在 网络上指定IP地址和端口号,“互联网联网标准”指定多字节值必须用“大头”形式来表示 (从最有意义的字节到最无意义的字节),一般称之为“网络字节”( network-byte)顺序。 有一系列的函数可用于多字节数的转换,把它们从主机字节顺序转换成网络字节顺序, 反之亦然。下面四个API函数便将一个数从主机字节顺序转换成网络字节顺序: u_long htonl(ulong hostlong) int WSAHton1( OCKET S u_long hostlong ).long FAR* Ipnetlong u_ short hons(ushort hostshort) int WSAHtons( SOCKET S short hostshort u_short FAr* 1pnetshort hton和 WSAHtonl的 hosting参数是按主机字节顺序的一个4字节数。 htonl函数返回的数 顺序是网络字节顺序,而 WSAHtonl函数通过 Ipnetlong i参数返回的数顺序是网络字节顺序 hons和 WSAHtons的 hotshot参数是按主机字节顺序的一个2字节数。 hons函数把这个数当作 按网络字节顺序的一个2字节值返回,而 WSAHtons函数通过 Ipnetshort参数把这个数返回。 下面这四个是前面四个函数的反向函数:它们把网络字节顺序转换成主机字节顺序 u_long ntohl(u_long netlong) int WsaNtoh1 u_long netlong. u_long FAR* Iphostlong
c p字段是一个空中止字符串,它认可点式表示法的 I P地址。注意,这个函数把 I P地址当作 一个按网络字节顺序排列的 3 2位无符号长整数返回(网络字节顺序在下面的“字节排序”小 节中简要说明)。 1. 特殊地址 对于特定情况下的套接字行为,有两个特殊 I P地址可对它们产生影响。特殊地址 I N A D D R _ A N Y允许服务器应用监听主机计算机上面每个网络接口上的客户机活动。一般情况 下,在该地址绑定套接字和本地接口时,网络应用才利用这个地址来监听连接。如果你有一 个多址系统,这个地址就允许一个独立应用接受发自多个接口的回应。 特殊地址I N A D D R _ B R O A D C A S T用于在一个I P网络中发送广播U D P数据报。要使用这个 特殊地址,需要应用设置套接字选项 S O _ B R O A D C A S T。第9章将对该选项进行详细论述。 2. 字节排序 针对“大头”(b i g - e n d i a n)和“小头”(l i t t l e - e n d i a n)形式的编号,不同的计算机处理器 的表示方法有所不同,这由各自的设计决定。比如, Intel 86处理器上,用“小头”形式来表 示多字节编号:字节的排序是从最无意义的字节到最有意义的字节。在计算机中把 I P地址和 端口号指定成多字节数时,这个数就按“主机字节”(h o s t - b y t e)顺序来表示。但是,如果在 网络上指定 I P地址和端口号,“互联网联网标准”指定多字节值必须用“大头”形式来表示 (从最有意义的字节到最无意义的字节),一般称之为“网络字节”(n e t w o r k - b y t e)顺序。 有一系列的函数可用于多字节数的转换,把它们从主机字节顺序转换成网络字节顺序, 反之亦然。下面四个A P I函数便将一个数从主机字节顺序转换成网络字节顺序: h t o n l和W S A H t o n l的h o s t l o n g参数是按主机字节顺序的一个 4字节数。h t o n l函数返回的数 顺序是网络字节顺序,而 W S A H t o n l函数通过 l p n e t l o n g参数返回的数顺序是网络字节顺序。 h t o n s和W S A H t o n s的h o s t s h o r t参数是按主机字节顺序的一个 2字节数。h t o n s函数把这个数当作 按网络字节顺序的一个2字节值返回,而W S A H t o n s函数通过l p n e t s h o r t参数把这个数返回。 下面这四个是前面四个函数的反向函数:它们把网络字节顺序转换成主机字节顺序: 104计计第二部分附Winsock API 下载
CAa°pd0105 下载 u short ntohs(u short netshort int WsANtohs( SOCKET u short netshort u_short FAR* lphostshort 现在,我们打算演示一下如何利用上面描述的 inet addr和 tons函数来创建 SOCKADDR IN结构 SOCKADDRIN InternetAddr INT nPortId= 5150 InternetAddr sin_family AF_INet // Convert the proposed dotted Internet address 136 149.3. 29 // to a 4-byte integer assign it to sin_addr InternetAddr sin_addr. s_addr inet addr("136.149. 3. 29 // The nPortId variable is stored in host-byte order. Convert // nPortId to network-byte order, and assign it to sin_port InternetAddr sin_port htons(nPortId) 6.14创建套接字 创建一个IP套接字的好处是便于应用能够通过TCP、UDP和IP协议进行通信。如要用TCP 协议打开一个IP套接字,需调用带有地址家族 AF INET和套接字类型 SOCK STREAM的 socket函数或 WSASocket函数,并把协议字段设成0,方式如下 s= socket(AF__INET, SOCK_ STREAM, 0); s WSASocket(AF_INET, SOCK STREAM, 0, NULL, 0 WSA_ OVERLAPPED) 要利用UDP协议打开IP套接字,只须指定套接字类型,用这个指定的套接字类型代替 socket函数中的 SOCK STREAM和上面的 WSASocket调用。还可以打开一个套接字通过IP直 通信。这是把套接字类型设成 SOCK RAW来完成的。第13章将对 SOCK RAW选项进行深 6.1.5名字解析 Winsock应用打算通过IP和主机通信时,必须知道这个主机的IP地址。依用户看来,IP地 址是不容易记的。在指定机器时,许多人更愿意利用一个易记的、友好的主机名而不是IP地 址。 Winsock提供了两个支持函数,它们有助于用户把一个主机名解析成IP地址。 Windows套接字 gethostbyname和 WSAAsynGetHost By Name API函数从主机数据库中取l 与指定的主机名对应的主机信息。两个函数均返回一个 HOSTENT结构,该结构的格式如下: struct hostent char Far* h name har FAr* Far*aliases
现在,我们打算演示一下如何利用上面描述的 i n e t _ a d d r 和 h t o n s 函数来创建 S O C K A D D R _ I N结构。 6.1.4 创建套接字 创建一个I P套接字的好处是便于应用能够通过 T C P、U D P和I P协议进行通信。如要用 T C P 协议打开一个 I P套接字,需调用带有地址家族 A F _ I N E T和套接字类型 S O C K _ S T R E A M的 s o c k e t函数或W S A S o c k e t函数,并把协议字段设成0,方式如下: 要利用 U D P协议打开 I P套接字,只须指定套接字类型,用这个指定的套接字类型代替 s o c k e t函数中的S O C K _ S T R E A M和上面的W S A S o c k e t调用。还可以打开一个套接字通过 I P直 接通信。这是把套接字类型设成 S O C K _ R AW来完成的。第 1 3章将对S O C K _ R AW选项进行深 入探讨。 6.1.5 名字解析 Wi n s o c k应用打算通过I P和主机通信时,必须知道这个主机的 I P地址。依用户看来, I P地 址是不容易记的。在指定机器时,许多人更愿意利用一个易记的、友好的主机名而不是 I P地 址。Wi n s o c k提供了两个支持函数,它们有助于用户把一个主机名解析成 I P地址。 Wi n d o w s套接字g e t h o s t b y n a m e和WSAAsynGetHostByName API函数从主机数据库中取回 与指定的主机名对应的主机信息。两个函数均返回一个 H O S T E N T结构,该结构的格式如下: 第6章计地址家族和名字解析计计105 下载
106第二部分mnky Chinaopub.com 下载 short h-addrtype: h_length char FAR FAR w h addr list h name字段是正式的主机名。如果网络采用了“域内命名系统”(DNS),它就是导致命 名服务器返回响应的“全限定域名”(FQDN)。如果网络使用一个本地“多主机”文件,主机 名就是IP地址之后的第一个条目。 h aliases字段是一个由主机备用名组成的空中止数组。 h addrty pe表示即将返回的地址家族。 h length字段则对 h addr_list字段中的每一个地址定义 字节长度进行定义。 h addr list字段是一个由主机IP地址组成的空中止数组(可以为一个主机 分配若干个IP地址)。这个数组中的每个地址都是按网络字节顺序返回的。一般情况下,应用 程序都采用该数组中的第一个地址。但是,如果返回的地址不止一个,应用程序就会相应地 选择一个最恰当的,而不是一直都用第一个地址。 gethostbyname API函数的定义如下 struct hostent Far* gethostbyname const char FAr* name me参数表示准备查找的那个主机的友好名。如果这个函数调用成功,系统就会返回一 个指向 HOSTENT结构的指针。注意,保存 HOSTENT结构的是系统内存。应用程序不应该依 靠它来维护状态。由于该内存由系统维护,因此,你的应用程序不必释放这个已返回的结构。 WSAAsync By Name API函数是 gethostbyname函数的异步版,后一个函数在结束 时,利用 Windows消息向应用程序发出通知。 WSAAsynGetHost By Name的定义如下: HANDLE WSAAsyncGetHostBy Name( HWND hWnd nsigned int wMsg st char far* name char FAr* buf bwnd参数是窗口句柄,异步请求结束时,这个句柄将收到一条消息。wMsg参数是异步 请求结束时收到的窗口消息。name参数代表我们正在查找的主机之用户友好名。buf参数是 个指针,它指向接收 HOSTENT数据的那个数据域。这个缓冲区必须大于 HOSTENT结构,应 该设为 MAXGETHOSTSTRUCTI中定义的最大长度。 另外两个用于获得主机信息的函数是: gethostbyaddr和 WSAAsynGetHost By Name API函 数,它们是为获得与IP网络地址相应的主机信息而设计的。在有了主机IP地址,并打算查找 其用户友好名时,这两个函数非常有用。 gethostbyaddr函数的定义如下 struct HOSTENT FAR* gethostbyaddr( const char FAr addr int len int type adr参数是指向一个IP地址的指针,这个地址按网络字节顺序排列。len参数用于指定addr 参数的字节长度。type参数将指定AF_INET值,这个值表明指定类型是IP地址。 WSAAsync GetHostBy Addr AP函数是 gethostbyaddri函数的异步版
h _ n a m e字段是正式的主机名。如果网络采用了“域内命名系统”(D N S),它就是导致命 名服务器返回响应的“全限定域名”(F Q D N)。如果网络使用一个本地“多主机”文件,主机 名就是 I P地址之后的第一个条目。 h _ a l i a s e s字段是一个由主机备用名组成的空中止数组。 h _ a d d r t y p e表示即将返回的地址家族。 h _ l e n g t h字段则对h _ a d d r _ l i s t字段中的每一个地址定义 字节长度进行定义。h _ a d d r _ l i s t字段是一个由主机I P地址组成的空中止数组(可以为一个主机 分配若干个I P地址)。这个数组中的每个地址都是按网络字节顺序返回的。一般情况下,应用 程序都采用该数组中的第一个地址。但是,如果返回的地址不止一个,应用程序就会相应地 选择一个最恰当的,而不是一直都用第一个地址。 gethostbyname API函数的定义如下: n a m e参数表示准备查找的那个主机的友好名。如果这个函数调用成功,系统就会返回一 个指向H O S T E N T结构的指针。注意,保存 H O S T E N T结构的是系统内存。应用程序不应该依 靠它来维护状态。由于该内存由系统维护,因此,你的应用程序不必释放这个已返回的结构。 WSAAsyncGetHostByName API函数是g e t h o s t b y n a m e函数的异步版,后一个函数在结束 时,利用Wi n d o w s消息向应用程序发出通知。 W S A A s y n G e t H o s t B y N a m e的定义如下: b W n d参数是窗口句柄,异步请求结束时,这个句柄将收到一条消息。 w M s g参数是异步 请求结束时收到的窗口消息。 n a m e参数代表我们正在查找的主机之用户友好名。 b u f参数是一 个指针,它指向接收 H O S T E N T数据的那个数据域。这个缓冲区必须大于 H O S T E N T结构,应 该设为M A X G E T H O S T S T R U C T中定义的最大长度。 另外两个用于获得主机信息的函数是: g e t h o s t b y a d d r和WSAAsynGetHostByName API函 数,它们是为获得与 I P网络地址相应的主机信息而设计的。在有了主机 I P地址,并打算查找 其用户友好名时,这两个函数非常有用。 g e t h o s t b y a d d r函数的定义如下: a d d r参数是指向一个I P地址的指针,这个地址按网络字节顺序排列。 l e n参数用于指定a d d r 参数的字节长度。 t y p e 参数将指定 A F _ I N E T 值,这个值表明指定类型是 I P地址。 WSAAsyncGetHostByAddr API函数是g e t h o s t b y a d d r函数的异步版。 端口号 106计计第二部分附Winsock API 下载
chhs 第章地址家族和名字解析07 应用打算与运行于本地或远程计算机上的服务进行通信时,除了要知道远程计算机的IP 地址外,还必须知道服务的端口号。在使用TCP和UDP时,应用必须决定计划通过哪些端口 进行通信。有几个“已知的端口号”是服务器服务保留的,这些服务支持比TCP高级的协议 (比如TCP和SPX)。举个例子来说,端口21是为FTP预留的,端口80是为FTTP预留的。正如 前面提到的那样,已知的服务一般都采用1~1023之间的端口号来设置协议。如果你正在开发 个不使用任何一种已知服务的TCP应用,就要考虑采用1023以上的端口,以免重复。通过 调用 getservbyname和 WSAAsyncGetServ By Name函数,便可获得已知服务的端口号。这两个 函数只从名为 services的文件中获得静态信息。 Windows95和 Windows98中,服务文件位于 % WINDOWS%下面:在 Windows nt和 Windows2000中,则位于% WINDOWS% System32 Drivers\Etc下面。 getservbyname函数的定义如下 struct servent FAR* getservbyname( const char FAR name, const char FAR proto name参数代表准备查找的服务名。举个例子来说,如果你正在定位FTP端口,就应该把 name参数设成指向字串“ftp"。 proto参数随便指向一个字串,这个字串表明name中的服务是 在这个参数中的协议下面注册的。 WSAAsyncGetServ By Name函数是 getservbyname函数的异 Windows2000中有一个新的注册和请求TCP及UDP服务信息的动态方法。服务器应用可 利用 WSASetservice函数来注册服务名、IP地址和服务的端口号。客户机应用可利用这三个API 函数的组合请求这条服务信息,这三个函数是 WSALookup Service Begin、 WSALookup ServiceNext 和 WSALookupServiceEnd。第10章将对此进行讨论 62红外线套接字 红外线套接字称为 IrSock,它是一个令人兴奋不已的新技术,首先在 Windows平台上亮相 红外线套接字允许两台计算机通过红外线串行端口进行通信。目前,红外线套接字可在 Windows98和 Windows2000上使用。红外线套接字不同于传统意义上针对便携机的短暂性而 设计的套接字。它们展示了一种新的名字解析模型,下一小节中将对此进行讨论 621定址 由于带有“红外线数据联盟”( Infrared Data association,IrDA)设备的大多数计算机可 能经常性地拆卸,传统的名字解析方案不能满足人们的需求。传统解析方法充当命名服务器 之类的静态资源——人们在移动正在运行网络客户任务的手提式电脑或膝上型计算机时,是 不能使用这些资源的。为解决这一问题,IrDA就设计成了这样:无须在整个大型网络上,只 须用一种特定的方式浏览范围内的资源,因此,IDA没有使用标准的 Winsock命名服务函数和 IP定址。相反,命名服务已并入通信流,另外还引入了一个新的地址家族,以支持与红外线 串行端口绑定在一起的服务。 IrSock地址结构中包含一个服务名(它对绑定和连接调用中所使 用的应用进行描述)和一个设备标识符(描述运行服务的设备)。这里的服务名和设备标识符 类似于传统TCPP套接字所用的IP地址和端口号字元组。 IrSock地址结构的定义如下 typedef struct sockaddr_irda t
第6章计地址家族和名字解析计计107 下载 应用打算与运行于本地或远程计算机上的服务进行通信时,除了要知道远程计算机的 I P 地址外,还必须知道服务的端口号。在使用 T C P和U D P时,应用必须决定计划通过哪些端口 进行通信。有几个“已知的端口号”是服务器服务保留的,这些服务支持比 T C P高级的协议 (比如T C P和S P X)。举个例子来说,端口 2 1是为F T P预留的,端口8 0是为F T T P预留的。正如 前面提到的那样,已知的服务一般都采用 1 ~ 1 0 2 3之间的端口号来设置协议。如果你正在开发 一个不使用任何一种已知服务的 T C P应用,就要考虑采用 1 0 2 3以上的端口,以免重复。通过 调用g e t s e r v b y n a m e和W S A A s y n c G e t S e r v B y N a m e函数,便可获得已知服务的端口号。这两个 函数只从名为s e r v i c e s的文件中获得静态信息。 Windows 95和Windows 98中,服务文件位于 % W I N D O W S%下面;在 Windows NT 和 Windows 2000 中,则位于% W I N D O W S% \ S y s t e m 3 2 \ D r i v e r s \ E t c下面。g e t s e r v b y n a m e函数的定义如下: n a m e参数代表准备查找的服务名。举个例子来说,如果你正在定位 F T P端口,就应该把 n a m e参数设成指向字串“ f t p”。p r o t o参数随便指向一个字串,这个字串表明 n a m e中的服务是 在这个参数中的协议下面注册的。 W S A A s y n c G e t S e r v B y N a m e函数是g e t s e r v b y n a m e函数的异 步版。 Windows 2000中有一个新的注册和请求 T C P及U D P服务信息的动态方法。服务器应用可 利用W S A S e t S e r v i c e函数来注册服务名、I P地址和服务的端口号。客户机应用可利用这三个 A P I 函数的组合请求这条服务信息,这三个函数是W S A L o o k u p S e r v i c e B e g i n、W S A L o o k u p S e r v i c e N e x t 和W S A L o o k u p S e r v i c e E n d。第1 0章将对此进行讨论。 6.2 红外线套接字 红外线套接字称为I r S o c k,它是一个令人兴奋不已的新技术,首先在Wi n d o w s平台上亮相。 红外线套接字允许两台计算机通过红外线串行端口进行通信。目前,红外线套接字可在 Windows 98和Windows 2000上使用。红外线套接字不同于传统意义上针对便携机的短暂性而 设计的套接字。它们展示了一种新的名字解析模型,下一小节中将对此进行讨论。 6.2.1 定址 由于带有“红外线数据联盟”(Infrared Data Association, IrDA)设备的大多数计算机可 能经常性地拆卸,传统的名字解析方案不能满足人们的需求。传统解析方法充当命名服务器 之类的静态资源—人们在移动正在运行网络客户任务的手提式电脑或膝上型计算机时,是 不能使用这些资源的。为解决这一问题, I r D A就设计成了这样:无须在整个大型网络上,只 须用一种特定的方式浏览范围内的资源,因此, I r D A没有使用标准的Wi n s o c k命名服务函数和 I P定址。相反,命名服务已并入通信流,另外还引入了一个新的地址家族,以支持与红外线 串行端口绑定在一起的服务。 I r S o c k地址结构中包含一个服务名(它对绑定和连接调用中所使 用的应用进行描述)和一个设备标识符(描述运行服务的设备)。这里的服务名和设备标识符 类似于传统T C P / I P套接字所用的I P地址和端口号字元组。I r S o c k地址结构的定义如下:
108第二部分Wmky 下载 u_short irdaAddress Family: irdaDevicelD[4] irdaserviceName [25] SOCKADDRIRDA: rdaAddressFamily字段一直都是 AF IRDA. irdaDeviceID是一个4字符的字串,用于唯 性地标识特定服务所运行的设备。在建立 IrSock服务器时,这个字段是忽略不计的。但是对客 户机而言,却非常重要,因为它指定的是准备连接的那个IrDA设备(也可能有若干个)。最后, rdaServicename字段是服务名,应用要么利用这项服务对其本身进行注册,要么试着与这项 服务建立连接。 622名字解析 定址可以利用“IrDA逻辑服务访问点选择符( LSAP-SEL)”或“信息访问服务”(IAS) 注册的服务为基础。IAS从一个 LSAP-SEL中摘出一项服务,并把它置入用户友好的文本服务 名中,方式和互联网域名服务器把名字映射到数字化IP地址差不多。要成功建立一个连接 既可以用LSAP-SEL,又可以用用户友好名。不过,用户友好名需要名字解析。大多数时候 都不要使用直接的 LSAP-SEL“地址”,因为IrDA服务的地址空间是限制了的。Win32实施方 案允许 LSAP-SEL整数标识符,标识符的范围是1到127。从本质上说,我们可把IAS服务器当 作一个WINS服务器,因为它把 LSAP-SEL和一个文字化的服务名关联在一起。 事实上的IAS条目有三个重要字段:类名、属性和属性值。举个例子来说,一个服务器希 望在服务名 MyServer下对其本身进行注册。这是服务器通过相应的 SOCKADDR_IRDA结构执 行绑定调用时完成的。这种情况一旦发生,就会增加一个IAS条目,该条目中包括类名 MyServer、属性 IrDA: Tiny TP:Lsap-SEL和属性值3。属性值就是下一个未用过的LSAP-SEL, 这个LSAP-SEL是系统根据注册来分配的。另一方面,客户机向连接调用投递一个 SOCKADDR_IRDA结构。随后便开始IAS查找,查找带有类名 MyServer和属性 IrDA: Tiny TP: Lsap-SEL的那项服务。IAS查询会返回3这个值。用户可利用 getsocketopt调用中 的套接字选项 IRLMP IAS QUERY来定制自己的IAS查询。 如果打算完全忽略IAS(一般不建议使用),则可为客户机准备连接的服务名或终端直接 指定一个 LASP-SEL地址。忽略IAS后,就只能和不提供任何IAS注册的老IrDA设备(比如红 外线打印机)进行通信。把 SOCKADDR IRDA结构中的服务名指定为 LSAP-SEL-xxx,就可 忽略IAS注册和査找。其中,xxx处是属性值,其范围在1到127之间。对服务器而言,这样会 直接为该服务器分配特定的 LSAP-SEL地址(假定这个 LSAP-SEL地址尚未使用)。对客户机 而言,这样会忽略IAS查找,并试图马上与运行于指定的 LSAP-SEL上的任何一项服务建立连 623红外线设备列举 由于红外线设备的使用地点不固定,因此,必须有一种方法,可以动态地把特定范围内 的所有可用红外线设备列举出来。我们先从 Windows ce实施方案和 Windows98及 Windows 2000实施方案之间的几点差别谈起。 Windows ce先于其他平台支持 IrSock,并提供少量与红 外线设备有关的信息。后来, Windows98和 Windows2000也开始支持 IrSock,但它们新增了 另外的“提示”信息,该信息是由列举请求返回的(关于提示信息,我们稍后将简要论述)
i r d a A d d r e s s F a m i l y字段一直都是A F _ I R D A。i r d a D e v i c e I D是一个4字符的字串,用于唯一 性地标识特定服务所运行的设备。在建立 I r S o c k服务器时,这个字段是忽略不计的。但是对客 户机而言,却非常重要,因为它指定的是准备连接的那个 I r D A设备(也可能有若干个)。最后, i r d a S e r v i c e N a m e字段是服务名,应用要么利用这项服务对其本身进行注册,要么试着与这项 服务建立连接。 6.2.2 名字解析 定址可以利用“ I r D A逻辑服务访问点选择符( L S A P - S E L)”或“信息访问服务”(I A S) 注册的服务为基础。 I A S从一个L S A P - S E L中摘出一项服务,并把它置入用户友好的文本服务 名中,方式和互联网域名服务器把名字映射到数字化 I P地址差不多。要成功建立一个连接, 既可以用L S A P - S E L,又可以用用户友好名。不过,用户友好名需要名字解析。大多数时候, 都不要使用直接的 L S A P - S E L“地址”,因为I r D A服务的地址空间是限制了的。 Wi n 3 2实施方 案允许L S A P - S E L整数标识符,标识符的范围是 1到1 2 7。从本质上说,我们可把 I A S服务器当 作一个W I N S服务器,因为它把L S A P - S E L和一个文字化的服务名关联在一起。 事实上的I A S条目有三个重要字段:类名、属性和属性值。举个例子来说,一个服务器希 望在服务名M y S e r v e r下对其本身进行注册。这是服务器通过相应的 S O C K A D D R _ I R D A结构执 行绑定调用时完成的。这种情况一旦发生,就会增加一个 I A S条目,该条目中包括类名 M y S e r v e r、属性I r D A : Ti n y T P : L s a p - S E L和属性值3。属性值就是下一个未用过的 L S A P - S E L, 这个 L S A P - S E L 是系统根据注册来分配的。另一方面,客户机向连接调用投递一个 S O C K A D D R _ I R D A 结构。随后便开始 I A S 查找,查找带有类名 M y S e r v e r 和属性 I r D A : Ti n y T P : L s a p - S E L的那项服务。I A S查询会返回3这个值。用户可利用 g e t s o c k e t o p t调用中 的套接字选项I R L M P _ I A S _ Q U E RY来定制自己的I A S查询。 如果打算完全忽略 I A S(一般不建议使用),则可为客户机准备连接的服务名或终端直接 指定一个L A S P - S E L地址。忽略I A S后,就只能和不提供任何 I A S注册的老 I r D A设备(比如红 外线打印机)进行通信。把 S O C K A D D R _ I R D A结构中的服务名指定为 L S A P - S E L - x x x,就可 忽略I A S注册和查找。其中, x x x处是属性值,其范围在 1到1 2 7之间。对服务器而言,这样会 直接为该服务器分配特定的 L S A P - S E L地址(假定这个 L S A P - S E L地址尚未使用)。对客户机 而言,这样会忽略 I A S查找,并试图马上与运行于指定的 L S A P - S E L上的任何一项服务建立连 接。 6.2.3 红外线设备列举 由于红外线设备的使用地点不固定,因此,必须有一种方法,可以动态地把特定范围内 的所有可用红外线设备列举出来。我们先从 Windows CE实施方案和Windows 98及Wi n d o w s 2 0 0 0实施方案之间的几点差别谈起。 Windows CE先于其他平台支持I r S o c k,并提供少量与红 外线设备有关的信息。后来, Windows 98和Windows 2000也开始支持I r S o c k,但它们新增了 另外的“提示”信息,该信息是由列举请求返回的(关于提示信息,我们稍后将简要论述)。 108计计第二部分附Winsock API 下载
0a109 这样一来, Windows ce的 AF irda. h头文件中包含的是原始的、少量的结构定义;但是,其他 平台提供的新的头文件中包含的则是目前支持 IrSock的各个平台的条件结构定义。为了保持 致,我们建议大家采用较新的 Af irda. h头文件 列举临近红外线设备的方法是采用 getsockopt的 IRLMP ENUM_ DEVICE命令。 DEVICELIST结构被当作 optval参数投递。这里有两个结构,一个针对 Windows98和 Windows 2000,另一个针对 Windows Ce。这两个结构的格式如下 typedef struct _WINDOWS_DEVICELIST numDeyice WINDOWS_ IRDA_DEVICE_INFO Device[1]: F WINDOWS_DEVICELIST,*PWI NDOWS_DEVICELIST, FAR *LPWINDOWS_DEVICELIST typedef struct _WCE_DEVICELIST ULONI numDevice wCE_ IRDA DEⅤ ICEINF0 Device[l I WCE_ DEVICELIST, *PWCE-DEVICELIST Windows98和 Windows2000结构与 Windows ce结构之间的唯一区别是 Windows98和 indows2000结构中包含一个 WINDOWS IRDA DEⅤ ICE INFO数组,该数组与WCE IRDA_DEⅤ ICE INFO结构的数组相对应。条件性的# define指令根据目标平台,声明 DEⅤ ICELIST结构是正确的。同样,也有对 IRDA DEⅤ ICE INFO结构的两个声明 typedef struct -WINDOWS_IRDADEVICEINFO u_char irdadeviceID[4] har irdaDeviceName [22]: u char irdadevicehints1 u char irdaDeviceHints2 u_char irda charset: WINDOWS_IRDA_DEVICE_INFO, *PWINDOWS_IRDA_DEVICE_INFO FAR *LPWINDONS_IRDA_DEVICE_INFO typedef struct -WCE-IRDADEVICE_INFO u_char irdadeviceID[4]: har irdadeviceName [22] u_char Reserved[2] WCE_IRDA_DEVICE_INFO. *PWCE_IRDA_DEVICE_INFO: # define指令根据目标平台,向正确的结构定义声明 IRDA DEVICE INFO。 正如前面提到的那样,真正用于列举红外线设备的函数是带有 IRLMP ENUM DEⅤICES 选项的 getsockopt函数。下面这一段代码,可把邻近的所有红外线设备ID列举出来 SOCKET devicelist delist DWORD dwListLen=sizeof(DEVICELIST) sock WSASocket(AF_IRDA, SOCK STREAM, 0, NULL, 0 WSA__OVERLAPPED) delist. numDevice = 0:
这样一来,Windows CE的A F _ i r d a . h头文件中包含的是原始的、少量的结构定义;但是,其他 平台提供的新的头文件中包含的则是目前支持 I r S o c k的各个平台的条件结构定义。为了保持一 致,我们建议大家采用较新的 A f _ i r d a . h头文件。 列举临近红外线设备的方法是采用 g e t s o c k o p t的I R L M P _ E N U M _ D E V I C E命令。 D E V I C E L I S T结构被当作o p t v a l参数投递。这里有两个结构,一个针对 Windows 98和Wi n d o w s 2 0 0 0,另一个针对Windows CE。这两个结构的格式如下: Windows 98和Windows 2000结构与Windows CE结构之间的唯一区别是 Windows 98和 Windows 2000结构中包含一个 W I N D O W S _ I R D A _ D E V I C E _ I N F O数组,该数组与 W C E _ I R D A _ D E V I C E _ I N F O结构的数组相对应。条件性的 # d e f i n e指令根据目标平台,声明 D E V I C E L I S T结构是正确的。同样,也有对 I R D A _ D E V I C E _ I N F O结构的两个声明: # d e f i n e指令根据目标平台,向正确的结构定义声明 I R D A _ D E V I C E _ I N F O。 正如前面提到的那样,真正用于列举红外线设备的函数是带有 I R L M P _ E N U M _ D E V I C E S 选项的g e t s o c k o p t函数。下面这一段代码,可把邻近的所有红外线设备 I D列举出来: 第6章计地址家族和名字解析计计109 下载
110 第二部分 Winsock API China-pub.com 下载 dwRet getsockopt(sock, SOL_IRLMP, I RLMP_ENUMDEVICES (char *)&delist, &dwListLen) 在向 getsockopt调用投递一个DEⅤ CELIST结构之前,别忘了把 num Device字段设成0 次成功列举会把 num Device字段设成一个大于0的值,并把 Device字段中 IRDA DEVICE INFO 结构数量设为前一个值。同时,在实际应用中,为检查新使用的设备,可能会多次执行 getsockopt举个例子来说,一个很好的例子就是试着进行五次或少于五次的红外线设备查找 方法很简单:在未成功列举之后,利用短期调用 Sleep,把该调用置入循环即可。 现在,大家已知道如何列举红外线设备,创建一个客户机或服务器就更简单了。同级的 服务器端更为简单,因为它像一个“普通”服务器。也就是说,不需要额外的步骤。创建 IrSock服务器的常见步骤如下: 1)建立一个地址家族 AF IRDA套接字和套接字类型 SOCK STREAM 2)用服务器的服务名填写一个 SOCKADDR IRDA结构 3)利用套接字句柄和 SOCKADDR IRDA结构调用bind 4)利用套接字句柄和 backlog边限调用 lister 5)为接入客户机锁定一个 acceptt调用 建立客户机的步骤稍微有些复杂,因为必须先把红外线设备列举出来。建立 IrSock客户 机所需步骤如下: 1)建立地址家族 AF IRDA套接字和套接字类型SOCK- STREAM 2)调用有 IRLMP ENUM DEⅥCES选项的 getsockopti函数,列举所有可用的红外线设备 3)针对返回的每个设备,利用设备ID和准备连接的服务名填写一个 SOCKADDR_IRDA 结构。 4)利用套接字句柄和 SOCKADDR IRDA结构,调用 connect函数。针对步骤3)中所填的 结构,重复步骤4),直到连接成功。 624查询As 要知道特定服务是否在特定的设备上运行,有两种方法。第一种是真正与特定服务连 接:另一种是向IAS查询特定的服务名。两种方法都要求列举红外线设备,然后对每一个设备 进行查询直到达到目的或所有的设备都查完。执行查找是调用带有 IRLMP IAS_ QUERY选项 的 getsockopt函数来完成的。再次提醒大家注意,IAS_ QUERY结构有两个,一个针对 indows98和 Windows2000,另一个针对 Windows Ce。各结构的格式如下 typedef struct_WINDOWS_IAS_QUERY u_char irdaDeviceID[4] char irdaclassName[IAS_MAX_ClaSSNaMe] char irdaAttri bName[IAS_MAX_ATTRIBNAME] u_long irdaAttribType: LONG irdaAttribint struct u_char octetseq[IAS_MAX_OCTET-STRING]
在向g e t s o c k o p t调用投递一个D E V I C E L I S T结构之前,别忘了把n u m D e v i c e字段设成0。一 次成功列举会把n u m D e v i c e字段设成一个大于0的值,并把D e v i c e字段中I R D A _ D E V I C E _ I N F O 结构数量设为前一个值。同时,在实际应用中,为检查新使用的设备,可能会多次执行 g e t s o c k o p t。举个例子来说,一个很好的例子就是试着进行五次或少于五次的红外线设备查找。 方法很简单:在未成功列举之后,利用短期调用 S l e e p,把该调用置入循环即可。 现在,大家已知道如何列举红外线设备,创建一个客户机或服务器就更简单了。同级的 服务器端更为简单,因为它像一个“普通”服务器。也就是说,不需要额外的步骤。创建 I r S o c k服务器的常见步骤如下; 1) 建立一个地址家族A F _ I R D A套接字和套接字类型S O C K _ S T R E A M。 2) 用服务器的服务名填写一个 S O C K A D D R _ I R D A结构。 3) 利用套接字句柄和S O C K A D D R _ I R D A结构调用b i n d。 4) 利用套接字句柄和b a c k l o g边限调用l i s t e n。 5) 为接入客户机锁定一个a c c e p t调用。 建立客户机的步骤稍微有些复杂,因为必须先把红外线设备列举出来。建立 I r S o c k客户 机所需步骤如下: 1) 建立地址家族A F _ I R D A套接字和套接字类型S O C K - S T R E A M。 2) 调用有I R L M P _ E N U M _ D E V I C E S选项的g e t s o c k o p t函数,列举所有可用的红外线设备。 3) 针对返回的每个设备,利用设备 I D和准备连接的服务名填写一个 SOCKADDR_ IRDA 结构。 4) 利用套接字句柄和S O C K A D D R _ I R D A结构,调用c o n n e c t函数。针对步骤3)中所填的 结构,重复步骤4),直到连接成功。 6.2.4 查询IAS 要知道特定服务是否在特定的设备上运行,有两种方法。第一种是真正与特定服务连 接;另一种是向I A S查询特定的服务名。两种方法都要求列举红外线设备,然后对每一个设备 进行查询直到达到目的或所有的设备都查完。执行查找是调用带有 I R L M P _ I A S _ Q U E RY选项 的g e t s o c k o p t函数来完成的。再次提醒大家注意, I A S _ Q U E RY结构有两个,一个针对 Windows 98和Windows 2000,另一个针对Windows CE。各结构的格式如下: 110计计第二部分附Winsock API 下载
Ca°pd0 第6章地址家族和名字解析 111 下载 f irdaAttriboctetSeq u_long Len u_long Charset u_char UsrStr[IAS_MAX_USER STRING] irdaAttribUsrStr; f irdaAttribute WINDOWS_IAS_QUERY, *PWINDOWS.IAS_ QUERY FAR*LPWINDOWS_ IAS QUERY typedef struct_WCE_IAS_QUERY u char irdaclassName [61] char irdaAttribName [61 u_short irdaAttribType union int irdaAttriblnt struct int u__char 0ctetseq[1] u_char Reserved[3] f irdaAttriboctetSeq struct int char Char Set u_char UsrStr[l]: u_char Reserved[2] b irdaAttribUsrstr b irdaAttribute I WCE IAS_QUERY, *PWCEIAS QUERY 大家可看到,除了特定字符数组的长度不同之外,这两个结构的格式是差不多的 要对特定服务的LSAP-SEL数有多少进行查询,很简单:把 irda classname字段设为LSAP SEL的属性字串,即 IrDA: IrLMP: LsapSel,然后,把 irdaAttribute name字段设成准备查询的那 服务名。除此以外,还必须用范围内的有效设备来设置 irdadeviceID字段。 625创建套接字 红外线套接字的创建很简单。几乎不需要任何选项,这是因为 IrSock只支持面向连接的数 据流。下面的代码说明了如何利用 socket或 WSASocket调用来建立红外线套接字。由于 Winsock1.1的限制,必须采用 Windows CE的 socket s socket(AF_IRDA, SOCK_STREAM, 0): S= WSASocket(aF IRDA, SoCK STREAM, 0, NULL, 8 WSA FLAG OVERLAPPED) 如果不想因循守旧,可把 IRDA PROTO SICK STREAM当作上面任何一个函数的协议参 数投递出去。但系统不需要这个协议参数,因为传输目录中只有一个地址家族 AF IRDA条目
第6章计地址家族和名字解析计计111 下载 大家可看到,除了特定字符数组的长度不同之外,这两个结构的格式是差不多的。 要对特定服务的L S A P - S E L数有多少进行查询,很简单:把 i r d a C l a s s N a m e字段设为L S A P - S E L的属性字串,即I r D A : I r L M P : L s a p S e l,然后,把i r d a A t t r i b u t e N a m e字段设成准备查询的那 个服务名。除此以外,还必须用范围内的有效设备来设置 i r d a D e v i c e I D字段。 6.2.5 创建套接字 红外线套接字的创建很简单。几乎不需要任何选项,这是因为 I r S o c k只支持面向连接的数 据流。下面的代码说明了如何利用 s o c k e t或W S A S o c k e t调用来建立红外线套接字。由于 Winsock 1.1的限制,必须采用Windows CE的s o c k e t。 如果不想因循守旧,可把 I R D A _ P R O TO _ S I C K _ S T R E A M当作上面任何一个函数的协议参 数投递出去。但系统不需要这个协议参数,因为传输目录中只有一个地址家族 A F _ I R D A条目