CSAPP:网络编程(一)IP相关

IP地址

IP地址就是一个32位无符号整数。

struct in_addr{
    unsigned int s_addr;
};

IP的网络字节顺序

方法:大端法

unsigned long int htonl(unsigned long int hostlong);
unsigned short int htons(unsigned short int hostshort);

返回:按照网络字节顺序的值。

IP的主机字节顺序

方法: 小端法

unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort);

返回:按照主机字节顺序的值。
练习1.将16进制的参数转换成点分十进制。
hex2dd.c:

#include <stdio.h>
#include <arpa/inet.h>
int main(int argc,char * argv[])
{
    struct in_addr addr;
    unsigned int ip_h;
    sscanf(argv[1],"0x%x",&ip_h);
    unsigned int ip_n = htonl(ip_h);//按照网络字节顺序的值
    char *ip_s = NULL;
    addr.s_addr = ip_n;
    ip_s = inet_ntoa(addr); //将ip地址转换成点分十进制
    printf("ip_h : %x , ip_n : %x , addr_ip: %s \n",ip_h,ip_n,ip_s);
    return 0;
}

结果:

bigship@bigship-virtual-machine:~/netlearning$ ./hex2dd 0x8002c2f2
ip_h : 8002c2f2 , ip_n : f2c20280 , addr_ip: 128.2.194.242 

练习2.将成点分十进制IP地址转换成十六进制
dd2hex.c:

#include <stdio.h>
#include <arpa/inet.h>

int main(int argc ,char * argv[])
{
    struct in_addr addr;
    unsigned int ip_h;
    if(inet_aton(argv[1],&addr))//将点分十进制ip地址转换unsigned int
        ip_h = ntohl(addr.s_addr);//按照主机字节顺序的值
    else
        printf("error\n");
    printf("ip_h:0x%x\n",ip_h);
    return 0;

}

结果:

bigship@bigship-virtual-machine:~/netlearning$ ./dd2hex 128.2.194.242
ip_h:0x8002c2f2

域名

因特网客户端和服务器相互通信时使用的是IP地址。因为IP地址太过难记因此人们提出了域名,以及将域名映射到IP地址的机制。例如:www.baidu.com
这个映射是通过DNS(Domain Name System,域名系统)来维护的。

/*
 *DNS host entry structure
 */
 struct hostent{
     char *h_name; //主机的官方名称
     char ** h_aliases; //别名
     int h_addrtype; //主机地址的类型
     int h_length //地址的长度(字节)
     char **h_addr_list; //IP地址表

hostinfo.c:

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>

int main(int argc,char * argv[])
{
    char **pp;
    struct in_addr addr;
    struct hostent *hostp;
    if(argc!=2){
        fprintf(stderr,"usage %s:error",argv[0]);
        exit(0);
    }
    if(inet_aton(argv[1],&addr)){
        printf("by address\n");
        hostp = gethostbyaddr((const char *)(&addr),sizeof(addr),AF_INET);
        //返回和IP地址相关的主机条目
    }
    else{
        printf("by name\n");
        hostp = gethostbyname(argv[1]);
                //返回和域名相关的主机条目
    }
    printf("Official hostname: %s\n",hostp->h_name);
    for(pp = hostp->h_aliases;*pp;pp++){
        printf("alias: %s\n",*pp);
    }
    for(pp = hostp->h_addr_list;*pp;pp++){
        addr.s_addr=((struct in_addr *)*pp)->s_addr;
        printf("address: %s\n",inet_ntoa(addr));
    }
    return 0;
}

结果:

bigship@bigship-virtual-machine:~/netlearning$ ./hostinfo www.baidu.com
by name
Official hostname: www.a.shifen.com
alias: www.baidu.com
address: 119.75.218.70
address: 119.75.217.109
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章