【Winsock 提供的资料库函式】
Winsock 也提供了同步与非同步的网路资料库函式;不过读者们要知道,此处的资料库指的并非如 Informix, Oracle 等商业用途的资料库系统,而是指主机IP 位址及名称、well-known 服务的名称及 Socket 型态及所用的 port number、以及协定(protocol)名称及代码等。
【同步资料库函式】
首先我们来看一下第一组:gethostbyname() 及 gethostbyaddr() 函式
这两个函式的用途是让我们可以由某个主机名称求得它的 IP 位址,或是由它的 IP 位址求得它的名称。一般我们经常会用到的是由名称求得 IP 位址;因为很少人会去记某台机器的 IP 位址的,另外 TCP/IP 封包的 IP header 上也必须记载送、收主机的 IP 位址,而不是主机名称。
◎ gethostbyname():利用某一 host 的名称来获取该 host 的资料。
格式: struct hostent FAR * PASCAL FAR gethostbyname( const char FAR *name );
参数: name host 的名称
传回值: 成功 - 指向一个 hostent 结构的指标
失败 - NULL (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式是利用 host 名称来获取该主机的其他资料,如 host 的位址、别名,位址的型态、长度等。
◎ gethostbyaddr():利用某一 host 的 IP 位址来获取该 host 的资料。
格式: struct hostent FAR * PASCAL FAR gethostbyaddr( const char FAR *addr, int len, int type );
参数: addr network 排列方式的位址
len addr 的长度
type PF_INET(AF_INET)
传回值: 成功 - 指向一个 hostent 结构的指标
失败 - NULL (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式是利用 IP 位址来获取该主机的其他资料,如 host 的名称、别名,位址的型态、长度等。
程式中呼叫的方式分别如下:
char host_name[30];
struct hostent far *htptr;
/* 假设 host_name 的值已先设定为我们要求得资料的主机名称 */
htptr = (struct hostent FAR *) gethostbyname( (char far *) host_name )
struct in_addr host_addr;
struct hostent far *htptr;
/* 假设 host_addr 的值已先设定为我们要求得资料的主机的network byte order 方式的 IP 位址*/
htptr = (struct hostent FAR *) gethostbyaddr((char far *)&host_addr, 4,PF_INET)
一般言,程式中呼叫到 gethostbyname() 及 gethostbyaddr() 时,Winsock Stack 会先在 local 的 「hosts」档中找看看是否有这个主机的资料;如果没有,则可能再透过「领域名称服务」(Domain Name Service)的功能,向「名称伺服器」(Name Server)查询;所以呼叫这两个函式时,有时会等一下子才获得答覆。如果您想让程式执行快一些的话,可将常用主机的资料放在 hosts 档中,这样就不必透过 DNS 去查询了。
接下来我们来看 getservbyname() 及 getservbyport() 这两个函式。
大部份的读者应该都用过 telnet、mail、ftp、news 等服务应用程式;这些应用程式的协定,比如服务名称、伺服器端所用的 port number、以及 Socket 的型态,都是固定的;这些资料,我们就可以利用 getservbyname() 或 getservbyport()
来取得,而不必刻意去记颂它们。
◎ getservbyname():依照服务 (service) 名称及通讯协定(tcp/udp)来获取该服务的其他资料。
格式: struct servent * PASCAL FAR getservbyname( const char FAR *name, const char FAR *proto );
参数: name 服务名称
proto 通讯协定名称
传回值: 成功 - 一指向 servent 结构的指标
失败 - NULL (呼叫 WSAGetLastError() 可得知原因)
说明: 利用服务名称及通讯协定来获得该服务的别名、使用的 port 号码等。
◎ getservbyport():依照服务 (serv