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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章