网络信息
对于一个更加通用的服务器和客户端来说,应该使用网络信息来决定应该使用的地址与接口。
若权限足够,可将服务添加到/etc/services文件中已知服务列表,并在这个文件中为端口分配一个名字,使用户可以使用符号化的服务名而不是端口号的数字。另外,给定一个计算机名字,可通过调用解析地址的主机数据库函数来确定它的IP地址。
主机数据库函数:
/* Return entry from host data base which address match ADDR with
length LEN and type TYPE.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern struct hostent *gethostbyaddr (const void *__addr, __socklen_t __len,
int __type);
/* Return entry from host data base for host with NAME.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern struct hostent *gethostbyname (const char *__name);
/* Description of data base entry for a single host. */
struct hostent
{
char *h_name; /* Official name of host. */
char **h_aliases; /* Alias list. */
int h_addrtype; /* Host address type. */
int h_length; /* Length of address. */
char **h_addr_list; /* List of addresses from name server. */
#ifdef __USE_MISC
# define h_addr h_addr_list[0] /* Address, for backward compatibility.*/
#endif
};
如果没有查询的主机或地址相关数据项,这些信息函数将返回一个空指针。
打印正确形式的ip地址:
/* Convert Internet number in IN to ASCII representation. The return value
is a pointer to an internal array containing the string. */
extern char *inet_ntoa (struct in_addr __in) __THROW;
服务相关信息获取函数:
/* Return entry from network data base for network with NAME and
protocol PROTO.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern struct servent *getservbyname (const char *__name, const char *__proto);
/* Return entry from service data base which matches port PORT and
protocol PROTO.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern struct servent *getservbyport (int __port, const char *__proto);
/* Description of data base entry for a single service. */
struct servent
{
char *s_name; /* Official service name. */
char **s_aliases; /* Alias list. */
int s_port; /* Port number. */
char *s_proto; /* Protocol to use. */
};
__proto:指定服务协议类型(tcp:SOCK_STREAM, udp:SOCK_DGRAM)
demo
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
char *host, **names, **addrs;
struct hostent *hostinfo;
if(argc == 1){
char myname[256];
gethostname(myname, 255);
host = myname;
printf("my name = %s.\n", host);
}else
host = argv[1];
hostinfo = gethostbyname(host);
if(!hostinfo){
perror("gethostbyname ");
exit(-1);
}
printf("result for host %s.\n", host);
printf("name: %s\n", hostinfo->h_name);
printf("aliases:");
names = hostinfo->h_aliases;
while (*names)
{
printf("%s", *names);
names++;
}
printf("\n");
if(hostinfo->h_addrtype != AF_INET){
fprintf(stderr, "not a ip host!\n");
exit(-1);
}
addrs = hostinfo->h_addr_list;
while (*addrs)
{
printf(" %s", inet_ntoa(*(struct in_addr *)*addrs));
addrs ++;
}
printf("\n");
return 0;
}