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 下载