1、第第8章章 Winsock API 第第8章章 Winsock API 8.1 8.1 字节排序函数字节排序函数8.2 IP8.2 IP地址转换函数地址转换函数8.3 8.3 网络信息获取函数网络信息获取函数(数据库函数数据库函数)8.4 8.4 套接口选项函数套接口选项函数8.5 8.5 套接口套接口I/OI/O处理函数处理函数8.6 8.6 事件对象事件对象I/OI/O管理管理8.7 8.7 错误处理函数错误处理函数 8.8 Winsock 28.8 Winsock 2支持的其他函数支持的其他函数习题习题 第第8章章 Winsock API 8.1字节排序函数8.1.1 4字节主机字节顺序
2、的数转化为网络字节顺序htonl()和WSAHtonl()1函数格式在Winsock 1中提供的htonl()函数的格式是:u_long htonl(u_long hostlong);在Winsock 2中提供的WSAHtonl()函数的扩展格式是:第第8章章 Winsock API int WSAHtonl(SOCKET s,u_long hostlong,u_long FAR*lpnetlong);2函数参数说明这两个函数中各参数的说明如下:hostlong:传入参数,它是一个用主机字节顺序表示的将要被转换为网络字节顺序的32位数(即4个字节的数),u_long表示无符号长整型数。s:传入
3、参数,在Winsock 2提供的扩展格式中增加了标识套接口的描述字。lpnetlong:传出参数,一个指向32位的网络字节顺序数的指针。第第8章章 Winsock API 3函数返回信息 这两个函数的返回值差别较大,在使用时一定要注意。对于htonl()函数来说,如果该函数被调用时正确执行,则这个函数返回一个32位的TCP/IP网络字节顺序的数。对于WSAHtonl()函数来说,如果该函数被调用时正确执行,则这个函数的返回值为0,函数返回的32位网络字节顺序的数据是指针参数lpnetlong所指向的数。如果在调用时该函数发生错误,则返回SOCKET_ERROR错误信息,可以进一步使用WSAGe
4、tLastError()函数取得对该错误的具体描述。错误代码如下:第第8章章 Winsock API WSANOTINITIALISED:在调用本API之前应成功调用WSAStartup()。WSAENETDOWN:网络子系统失效。WSAENOTSOCK:描述字不是一个套接口。WSAEFAULT:指针参数lpnetlong不在有效的用户地址空间中。4函数使用说明该函数的使用比较简单,主要用来将一个32位的IP地址从主机字节顺序转化为网络字节顺序,具体用法可以参考第7章的网络程序实例。第第8章章 Winsock API 8.1.2 2字节主机字节顺序的数转化为网络字节顺序htons()和WSAH
5、tons()1函数格式 在Winsock 1中提供的htons()函数的格式是:u_short htons(u_short hostshort );在Winsock 2中提供的WSAHtons()函数的扩展格式是:u_short WSAHtons(SOCKET s,u_short hostshort,u_short FAR*lpnetshort );第第8章章 Winsock API 2函数参数说明这两个函数中各参数的说明如下:hostshort:传入参数,它是一个以主机字节顺序表示的将要被转换为网络字节顺序的16位数(即2字节数),u_short表示无符号短整型数。s:传入参数,Winsoc
6、k 2提供的扩展格式中增加的标识套接口的描述字。lpnetshort:传出参数,一个指向16位网络字节顺序数的指针。第第8章章 Winsock API 3函数返回信息htons()函数如果被调用时正确执行,则这个函数返回一个16位TCP/IP网络字节顺序的数。WSAHtons()函数如果被调用时正确执行,则这个函数返回0,函数返回的16位网络字节顺序的数据是指针参数lpnetshort所指向的数。如果在调用时该函数发生错误,则返回 S O C K E T _ E R R O R 错 误 信 息,可 以 进 一 步 使 用WSAGetLastError()函数取得对该错误的具体描述。错误代码与W
7、SAHtonl()函数的错误代码类似。4函数使用说明该函数一般用来将一个16位的TCP或UDP端口号从主机字节顺序转化为网络字节顺序,用法可以参考第7章的程序实例。第第8章章 Winsock API 8.1.3 4字节网络字节顺序的数转化为主机字节顺序ntohl()和WSANtohl()1函数格式在Winsock 1中提供的ntohl()函数的格式是:u_long ntohl(u_long netlong);在Winsock 2中提供的WSANtohl()函数的扩展格式是:u_long WSANtohl(SOCKET s,u_long netlong,u_long FAR*lphostlong
8、);第第8章章 Winsock API 2函数参数说明这两个函数的参数说明如下:netlong:传入参数,一个以网络字节顺序表示的32位数。s:传入参数,在Winsock 2中提供的扩充格式中增加的标识套接口的描述字。lphostlong:传出参数,指向一个32位主机字节顺序数的指针。3函数返回信息ntohl()函数在调用成功后,返回一个主机字节顺序的32位数。第第8章章 Winsock API WSANtohl()函数在调用正确时返回0,函数返回的32位主机字节顺序的数据是指针参数lphostlong所指向的数。如果调用错误,则返回错误信息SOCKET_ERROR,可以进一步使用WSAGet
9、LastError()函数取得对该错误的具体描述。具体错误代码与WSAHtonl()函数的错误代码类似。4函数使用说明该函数常用来将一个网络字节顺序表示的32位IP地址转化为主机字节顺序。第第8章章 Winsock API 8.1.4 2字节网络字节顺序的数转化为主机字节顺序ntohs()和WSANtohs()1函数格式在Winsock 1中提供的ntohs()函数的格式是:u_short ntohs(u_short netshort);在Winsock 2中提供的WSANtohs()函数的扩展格式是:u_short WSANtohs(SOCKET s,u_short netshort,u_s
10、hort FAR*lphostshort);第第8章章 Winsock API 2函数参数说明这两个函数的参数说明如下:netshort:传入参数,一个以网络字节顺序表示的16位数。s:传入参数,在Winsock 2提供的扩充格式中增加的一个标识套接口的描述字。lphostshort:传出参数,指向一个16位主机字节顺序数的指针。第第8章章 Winsock API 3函数返回信息ntohs()函数在调用成功后,返回一个主机字节顺序的16位数。WSANtohs()函数在调用正确时返回0,函数返回的16位主机字节顺序的数据是指针参数lphostshort所指向的数。如果调用错误,则返回错误信息SO
11、CKET_ERROR,可以进一步使用WSAGetLastError()函数取得对该错误的具体描述。具体错误代码与WSAHtonl()函数的错误代码类似。4函数使用说明该函数常用来将一个网络字节顺序表示的16位TCP或UDP端口号转化为主机字节顺序。第第8章章 Winsock API 8.2 IP地址转换函数8.2.1 点分十进制数表示的IP地址转换为网络字节顺序的IP地址inet_addr()1函数格式inet_addr()函数的格式如下:unsigned long inet_addr(const char FAR*cp);第第8章章 Winsock API 2函数参数说明该函数中的参数cp为
12、传入参数,是一个以“.”间隔的字符串,即一个点分十进制数表示的IP地址。3函数返回信息该函数调用成功后,返回一个无符号长整型数(Unsigned Long),它是以网络字节顺序表示的32位二进制IP地址。如果传入的字符串不是一个合法的Internet地址,如当“a.b.c.d”地址中任一项超过255时,则inet_addr()返回INADDR_NONE提示信息。第第8章章 Winsock API 4函数使用说明当IP地址用点分十进制数表示时,即4个字节的数以“.”间隔,则用这种格式书写的IP地址可有下列4种表示方式。(1)a.b.c.d:当四个部分都有固定的值时,则每一个部分被解释成一个字节的
13、数据,从左到右组成Internet 4字节地址。请注意,当一个Internet地址在Intel机器上表示成一个32位整型数时,则上述数据在计算机内部的表示为“d.c.b.a”。这是因为在Intel处理器内部,字中的字节是按由低到高的顺序存储的,即“小序在前”。第第8章章 Winsock API (2)a.b.c:对于一个只有三个部分组成的IP地址,最后一部分被解释成16位数据,并作为网络地址最右边的两个字节。(3)a.b:对于一个只有两个部分组成的IP地址,最后一部分解释成24位数据,并作为网络地址最右边的三个字节。(4)a:对于一个仅有一个部分的IP地址,将它的值直接存入网络地址而不做任何字
14、节重组。该函数的用法见第7章中的客户程序实例。第第8章章 Winsock API 8.2.2 网络字节顺序的IP地址转换为点分十进制数表示的IP地址inet_ntoa()1函数格式inet_ntoa()函数的格式如下:char*inet_ntoa(struct in_addr in);2函数参数说明该函数中的参数in为传入参数,表示一个结构型的IP主机地址。第第8章章 Winsock API 3函数返回信息该函数调用成功后,返回一个指向字符的指针,该指针指向一个文本型的缓冲区,缓冲区中存有用点分十进制形式表示的IP地址。如果函数调用失败的话,则返回一个空指针(NULL)。4函数使用说明该函数的
15、用法参见第7章中的服务器程序实例。第第8章章 Winsock API 8.3 网络信息获取函数网络信息获取函数(数据库函数数据库函数)8.3.1 获得主机名gethostname()gethostname()函数用来取得一台主机的名称信息。1函数格式该函数的格式如下:int gethostname(char FAR*name,int namelen);第第8章章 Winsock API 2函数参数说明gethostname()函数中各参数的说明如下:name:传出参数,一个指向将要存放主机名的缓冲区指针,当函数调用完成时,主机名被存入该缓冲区中。namelen:传入参数,缓冲区的长度。3函数返
16、回信息 如果函数调用时没有发生错误,则gethostname()函数返回0。如果函数调用失败,则返回SOCKET_ERROR错误信息。应用程序可以通过WSAGetLastError()来得到一个特定的错误代码,错误代码说明如下:第第8章章 Winsock API WSAEFAULT:名字长度参数太小。WSANOTINTIALISED:在应用这个API前,必须成功调用WSAStartup()。WSAENETDOWN:Windows Sockets实现检测到了网络子系统的错误。WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。4函数使用说明 该函数把本地主机名存放
17、入由name参数指定的缓冲区中。主机名的形式取决于Windows Sockets系统的实现,它可能是一个简单的主机名,或者是一个域名。不管是哪种形式,该函 数 返 回 的 名 字 必 定 可 以 在 g e t h o s t b y n a m e()和WSAAsyncGetHostByName()函数中使用。第第8章章 Winsock API 8.3.2 获得与套接口相连的远程协议地址getpeername()1函数格式getpeername()函数的格式如下:int getpeername(SOCKET s,struct sockaddr FAR*name,int FAR*namelen
18、);第第8章章 Winsock API 2函数参数说明该函数中各参数的说明如下:s:传入参数,一个已建立连接的套接口描述字。name:传出参数,指向返回的远程协议地址。namelen:传出参数,远程协议地址长度。3函数返回信息调用该函数时若无错误发生,则getpeername()函数返回0。如果调用失败,则返回SOCKET_ERROR错误信息,应用程序可通过调用WSAGetLastError()函数来获取对该错误的进一步描述。可获得的错误代码如下:第第8章章 Winsock API WSANOTINITIALISED:在使用此API之前应成功调用WSAStartup()。WSAENETDOWN
19、:Windows套接口实现检测到网络子系统失效。WSAEFAULT:namelen参数不够大。WSAEINPROGRESS:一个阻塞的Windows套接口调用正在运行中。WSAENOTCONN:套接口未建立连接。WSAENOTSOCK:描述字不是一个套接口。第第8章章 Winsock API 4函数使用说明getpeername()函数用于从套接口s中获取与它绑定的远程协议的地址信息,并把它存放在sockaddr类型的name结构中。它只能用于已经建立连接的套接口。对于数据报类型的套接口来说,它只能返回先前调用connect()函数时使用的对等端信息,在sendto()函数中使用过的对等端信息
20、不能被返回。第第8章章 Winsock API 8.3.3 获得套接口本地协议地址getsockname()1函数格式getsockname()函数的格式如下:int getsockname(SOCKET s,struct sockaddr FAR*name,int FAR*namelen);第第8章章 Winsock API 2函数参数说明该函数的参数说明如下:s:传入参数,标识一个套接口的描述字。name:传出参数,指向返回的本地协议地址的指针。namelen:传出参数,本地协议地址长度。当函数调用完成时,它可以返回实际的本地地址长度。第第8章章 Winsock API 3函数返回信息调用
21、该函数时若无错误发生,则getsockname()函数返回0。如果调用失败,则返回SOCKET_ERROR错误信息,应用程序可通过WSAGetLastError()函数来获取如下的错误代码:WSANOTINITIALISED:在使用此API之前应成功调用WSAStartup()。WSAENETDOWN:Windows套接口实现检测到网络子系统失效。WSAEFAULT:namelen参数不够大。WSAEINPROGRESS:一个阻塞的Windows套接口调用正在运行中。WSAENOTSOCK:描述字不是一个套接口。WSAEINVAL:套接口未用bind()捆绑。第第8章章 Winsock API
22、 4函数使用说明getsockname()函数用于获取一个套接口的协议地址,它用于一个已绑定或已连接套接口。本调用特别适用于如下情况:未调用bind()就调用了connect(),这时惟有getsockname()调用可以获知系统内定的本地地址。在返回时,namelen参数包含了名字的实际字节数。若一个套接口与INADDR_ANY绑定,即该套接口可以用任意的主机地址,此时除非调用connect()或accept()来连接,否则getsockname()将不会返回主机IP地址的任何信息。除非套接口被连接,Windows套接口应用程序不应假设IP地址会从INADDR_ANY变成其他地址。这是因为对
23、于一个有多个IP地址的主机来说,除非套接口被连接,否则该套接口所用的IP地址是不可知的(即不能被确定是哪一个)。第第8章章 Winsock API 8.3.4 根据主机名取得主机信息gethostbyname()或WSAAsyncGetHostByName()gethostbyname()和WSAAsynGetHostByName()这两个Winsock API函数从主机数据库中取回与指定的主机名对应的主机信息。这两个函数均返回一个hostent结构型的量,所以先介绍一下该结构的格式。hostent结构的定义如下:struct hostent char FAR*h_name;/*officia
24、l name of host*/char FAR*FAR*h_aliases;/*alias list*/short h_addrtype;/*host address type*/第第8章章 Winsock API short h_length;/*length of address*/char FAR*FAR*h_addr_list;/*list of addresses*/#define h_addr h_addr_list0/*address,for backward compat*/;第第8章章 Winsock API 该结构中各字段的含义如下:h_name:该字段是正式的主机名。h
25、_aliases:它是二维字符指针,返回一台主机的所有别名(即别名列表)。h_addrtype:表示主机地址类型,如AF_INET表示IPv4地址。h_length:该字段可以返回主机地址的字节数。h_addr_list:该字段返回一个主机的所有IP地址,因为一台主机可以分配若干个IP地址(当然这主要是对服务器而言的)。这个数组中的每个地址都是按网络字节顺序返回的。一般情况下,应用程序都采用该数组中的第一个地址。但是,如果返回的地址不止一个,应用程序就会相应地选择一个最恰当的地址,而不是一直都用第一个地址。第第8章章 Winsock API h_addr:是为了保持向后兼容而定义的字段,一般很
26、少使用。1函数格式在Winsock 1中提供的gethostbyname()函数的格式是:struct hostent FAR*gethostbyname(const char FAR*name);在Winsock 1中提供的异步扩WSAAsyncGetHostByName()函数的格式是:第第8章章 Winsock API HANDLE WSAAsyncGetHostByName(HWND hWnd,unsigned int wMsg,const char FAR*name,char FAR*buf,int buflen);第第8章章 Winsock API 2函数参数说明gethostby
27、name()函数中各参数的说明如下:name:传入参数,是一个指向主机名的指针。WSAAsyncGetHostByName()函数是一个Windows异步扩展函数,它在函数结束时,利用Windows消息向应用程序发出通知,其各参数的含义是:hWnd:传入参数,是一个窗口句柄,表示当异步请求完成时,该窗口句柄应该收到一条消息。wMsg:传入参数,当异步请求完成时,将要接收的消息。第第8章章 Winsock API name:传入参数,指向主机名的指针。buf:传出参数,接收hostent数据的数据区指针。注意该数据区必须大于hostent结构的大小,这是因为Windows Sockets实现不仅
28、要用该数据区容纳hostent结构,而且hostent结构的成员引用的所有数据也要在该区域内。建议用户提供一个MAXGETHOSTSTRUCT字节大小的缓冲区。buflen:传入参数,上述数据区的大小。第第8章章 Winsock API 3函数返回信息调用该函数时如果没有错误发生,gethostbyname()函数返回如上所述的一个指向hostent结构的指针。如果调用失败则返回一个空指针,应用程序可以通过WSAGetLastError()来得到一个特定的错误代码,错误代码说明如下:WSANOTINTIALISED:在应用这个API前,必须成功调用WSAStartup()。WSAENETDOW
29、N:Windows Sockets实现检测到了网络子系统的错误。WSAHOST_NOT_FOUND:没有找到授权应答主机。WSATRY_AGAIN:没有找到非授权主机,或者服务器故障(SERVERFAIL)。第第8章章 Winsock API WSANO_RECOVERY:无法恢复的错误,如查询有格式错误(FORMERR)、拒绝服务(REFUSED)没有通信处理机、(NOTIMP)。WSANO_DATA:有效的名字,但没有关于请求类型的数据记录。WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。W S A E I N T R:阻 塞 调 用 被WSACance
30、lBlockingCall()取消了。第第8章章 Winsock API 4异步扩展函数返回信息WSAAsyncGetHostByName()函数是gethostbyname()函数的Windows异步扩展函数。所谓“异步”,指的是Windows Sockets的实现启动该操作后立刻回到调用方,并传回一个异步任务句柄,应用程序可以用它来标识该操作。当异步操作完成时,如果成功则将主机名和地址信息拷贝到buf缓冲区中,同时向句柄为hWnd的应用程序窗口发送一条消息(wMsg)。wParam参数包含了初次函数调用时返回的异步任务句柄,lParam的高16位包含着错误代码,该代码可以是Winsock2
31、.h中定义的任何错误。错误代码为0说明异步操作成功,在成功完成的情况下,提供给初始函数调用的缓冲区中包含了一个hostent结构。为存取该结构中的元素,初始的缓冲区指针应置为hostent结构的指针。第第8章章 Winsock API 若错误代码为WSAENOBUFS,则说明在初始调用时由buflen指出的缓冲区大小对于容纳所有的结果信息来说太小了。在这种情况下,lParam的低16位提供所有信息所需的缓冲区大小。如果应用程序认为获取的数据不够,它就可以在设置了足够容纳所需信息的缓冲区(也就是大于lParam低16位提供的数值)后,重新调用WSAAsyncGetHostByName()函数。错
32、 误 代 码 和 缓 冲 区 大 小 应 使 用WSAGETASYNCERROR和WSAGETASYNCBUFLEN宏从lParam中取出。这两个宏的定义如下:第第8章章 Winsock API#define WSAGETASYNCERROR(lParam)HIWORD(lParam)#define WSAGETASYNCBUFLEN(lParam)LOWORD(lParam)使用这些宏可以最大限度地提高应用程序源代码的可移植性。函数的返回值指出异步操作是否成功启动,注意它并不隐含操作本身的成功或失败(后面要介绍的其他异步函数的返回值也与它类似)。第第8章章 Winsock API 若操作成功
33、启动,则WSAAsyncGet-HostByName()返回一个HANDLE类型的非0值,它用来标识该异步请求任务的句柄。通过该句柄使用WSACancelAsyncRequest()函数可取消该操作,也可通过检查wParam消息参数,以匹配异步操作和完成消息。如果异步操作不能启动,WSAAsyncGetHostByName()返回一个0值,并且可使用WSAGetLastError()函数来获取如下的错误代码:WSANOTINITIALISED:在使用本API前必须进行一次成功的WSAStartup()调用。第第8章章 Winsock API WSAENETDOWN:Windows Socket
34、s实现已检测到网络子系统故障。WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。WSAEWOULDBLOCK:本异步操作此时由于Windows Sockets实现的资源或其他限制的制约而无法调度。在应用程序的窗口收到消息时可能会设置下列错误代码,它们可以通过WSAGETA-SYNCERROR宏从应答的消息lParam中取出:WSAENETDOWN:Windows Sockets实现已检测到网络子系统故障。第第8章章 Winsock API WSAENOBUFS:可用的缓冲区空间不足或没有。WSAHOST_NOT_FOUND:未找到授权应答主机。WSATRY_A
35、GAIN:未找到非授权应答主机,或SERVERFAIL。WSANO_RECOVERY:不可恢复性错误。WSANO_DATA:无请求类型的数据记录。第第8章章 Winsock API 8.3.5 根据主机地址取得主机信息gethostbyaddr()或WSAAsyncGetHostByAddr()这两个函数可以根据主机的IP地址取得主机名和主机地址等信息。1函数格式 在Winsock 1中提供的gethostbyaddr()函数的格式是:struct hostent FAR*gethostbyaddr(const char FAR*addr,int len,int type);第第8章章 Win
36、sock API 在Winsock 1中提供的异步扩展WSAAsyncGetHostByAddr()函数的格式是:HANDLE WSAAsyncGetHostByAddr(HWND hWnd,unsigned int wMsg,const char FAR*addr,int len,int type,char FAR*buf,int buflen);第第8章章 Winsock API 2函数参数说明gethostbyaddr()函数的参数说明如下:addr:传入参数,指向网络字节顺序地址的指针。len:传入参数,地址的长度,如果是IPv4类型的地址,则该值为4。type:传入参数,地址类型,如
37、为AF_INET。WSAAsyncGetHostByAddr()函数是gethostbyaddr()函数 的 异 步 版 本。它 的 其 他 参 数 以 及 返 回 信 息 与WSAAsyncGetHostByName()函数完全相同。第第8章章 Winsock API 3函数返回信息这两个函数返回的信息与通过名称获取主机信息的gethostbyname()函数相同。8.3.6 根据协议名取得主机协议信息getprotobyname()或WSAAsync-GetProtoByName()函数getprotobyname()WSAAsyncGetProtoByName()可以根据协议名称返回对应
38、的相关协议信息。它们都要使用到一个与协议有关的结构,该结构的定义如下:第第8章章 Winsock API struct protoentcharFAR*p_name;charFAR*FAR*p_aliases;short p_proto;该结构的成员有:p_name:正式的协议名。p_aliases:它是二维字符指针,返回一个协议的所有别名。p_proto:以主机字节顺序排列的协议号。第第8章章 Winsock API 1函数格式在Winsock 1中提供的getprotobyname()函数的格式是:struct protoent FAR*getprotobyname(const char
39、FAR*name);在Winsock 1中提供的异步扩展WSAAsyncGetProtoByName()函数的格式是:HANDLE WSAAsyncGetProtoByName(HWND hWnd,unsigned int wMsg,const char FAR*name,char FAR*buf,int buflen);第第8章章 Winsock API 2函数参数说明getprotobyname()函数中的参数name为传入参数,指向协议名的指针。异步扩展格式中的buf是接收protoent数据的缓冲区指针,b u f l e n 为 该 缓 冲 区 的 大 小。其 他 参 数 与WSAA
40、syncGetHostByName()函数中的参数相同,返回信息的含义也一样。3函数返回信息如果没有错误发生,getprotobyname()返回如上所述的一个指向protoent结构的指针,如果调用失败,则返回一个空指针。应用程序可以通过WSAGetLastError()来得到一个如下所示的特定错误代码:第第8章章 Winsock API WSANOTINTIALISED:在应用这个API前,必须成功调用WSAStartup()。WSAENETDOWN:Windows Sockets实现检测到了网络子系统的错误。WSANO_RECOVERY:无法恢复的错误,如FORMERR、REFUSED、
41、NOTIMP等。WSANO_DATA:有效的名字,但没有关于请求类型的数据记录。第第8章章 Winsock API WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。W S A E I N T R:阻 塞 调 用 被WSACancelBlockingCall()取消了。WSAHOST_NOT_FOUND:没有找到协议。WSATRY_AGAIN:非正式的协议没有找到或服务器失败。WSAEFAULT:name参数不在有效的用户地址空间。第第8章章 Winsock API 8.3.7 根据协议号取得主机协议信息getprotobynumber()或WSAAsyncG
42、etProtoByNumber()getprotobynumber()和WSAAsyncGetProtoByNumber返回对应于给定协议号的相关协议信息。1函数格式在Winsock 1中提供的getprotobynumber()函数的格式是:struct protoent FAR*getprotobynumber(int number);第第8章章 Winsock API 在Winsock 1中提供的异步扩展WSAAsyncGetProtoByNumber()函数的格式是:HANDLE WSAAsyncGetProtoByNumber(HWND hWnd,unsigned int wMsg,
43、int number,char FAR*buf,int buflen);第第8章章 Winsock API 2函数参数说明参数number表示传入参数,是一个以主机字节顺序排列的协议号。异步扩展格式中的其他参数与WSAAsyncGetHostByName()函数中的参数含义相同。3函数返回信息函数的返回信息与通过协议名获取主机协议信息时的情况相同。第第8章章 Winsock API 8.3.8 根据服务名取得相关服务信息getservbyname()或WSAAsync-GetServByName()getservbyrvame()和WSAAsyncGetServByName()函数用于返回对应
44、于给定服务名和协议名的相关服务信息。这两个函数都要用到一个如下所示的结构:struct serventchar FAR*s_name;char FAR*FAR*s_aliases;short s_port;char FAR*s_proto;第第8章章 Winsock API 该结构中各成员的含义如下:s_name:正规的服务名。s_aliases:所有其他的可选服务名。s_port:连接该服务时需要用到的端口号,返回的端口号是以网络字节顺序排列的。s_proto:连接该服务时用到的协议名。第第8章章 Winsock API 1函数格式在Winsock 1中提供的getservbyname()函
45、数的格式是:struct servent FAR*getservbyname(const char FAR*name,const char FAR*proto);在 W i n s o c k 1 中 提 供 的 异 步 扩 展WSAAsyncGetServByName()函数的格式是:第第8章章 Winsock API HANDLE WSAAsyncGetServByName(HWND hWnd,unsigned int wMsg,const char FAR*name,const char FAR*proto,char FAR*buf,int buflen);第第8章章 Winsock A
46、PI 2函数参数说明这两个函数中各参数的说明如下:name:传入参数,一个指向服务名的指针。proto:传入参数,指向协议名的指针(可选)。如果这个指针为空,getservbyname()返回第一个name与s_name或者某一个s_aliases匹配的服务条目。否则,getservbyname()对name和proto都进行匹配。其他参数与WSAAsyncGetHostByName()函数中的参数含义相同。第第8章章 Winsock API 8.3.9 根据端口号取得相关服务信息getservbyport()或WSAAsync-GetServByPort()getservbyport()和W
47、SAAsyncGetServByPort()函数用于返回对应于给定端口号和协议名的相关服务信息。1函数格式在Winsock 1中提供的getservbyport()函数的格式是:struct servent FAR*getservbyport(int port,const char FAR*proto);第第8章章 Winsock API 在 W i n s o c k 1 中 提 供 的 异 步 扩 展WSAAsyncGetServByPort()函数的格式是:HANDLE WSAAsyncGetServByPort(HWND hWnd,unsigned int wMsg,int port,
48、const char FAR*proto,char FAR*buf,int buflen);第第8章章 Winsock API 2函数参数说明这两个函数中需要说明的参数如下:port:传入参数,给定的端口号,以网络字节顺序排列。proto:传入参数,指向协议名的指针(可选)。如果这个指针为空,getservbyport()返回第一个port与s_port匹配的服务条目。否则,getservbyport()对port和proto都进行匹配。其他参数与WSAAsyncGetHostByName()函数中的参数含义相同。第第8章章 Winsock API 8.3.10 网络信息获取函数应用实例本小节
49、举一个实例来说明以上介绍的网络信息获取函数的用法。本实例只使用了三个比较典型的函数,其他函数的用法与此类似。要说明的是,虽然这只是一个关于网络信息获取函数用法的实例,但该程序也是一个非常有用的实用程序,它可以获得一台主机的主机名、主机别名(如果有的话)、主机IP地址列表等信息。第第8章章 Winsock API/*调试环境:VC+6.0程序名称:host.cpp程序功能:该程序使用网络信息获取函数取得主机的有关信息,在程序中使用了以下三个函数:gethostname()gethostbyname()getprotobyname()命令格式:host*/第第8章章 Winsock API#inc
50、lude#include#includevoid main()WSADATAwsaData;intn;/存放主机名称 charhostname256;第第8章章 Winsock API/主机信息指针 hostent*pHostent;/主机协议信息指针 protoent *pProtoent;struct sockaddr_insa;if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)printf(Failed to load Winsock.n);return;第第8章章 Winsock API printf(-n);/获得主机名 if(gethostname(