socket基础编程(二)

网络信息

对于一个更加通用的服务器和客户端来说,应该使用网络信息来决定应该使用的地址与接口。
若权限足够,可将服务添加到/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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值