[CSAPP] 第三部分 第11章 网络 IP地址

来源:互联网 发布:我的世界版本 知乎 编辑:程序博客网 时间:2024/05/14 11:39

IP地址

IP地址是32位无符号整数。网络程序讲IP地址存放在struct in_addr 中

struct in_addr{    unsigned int s_addr;}

IP地址总是以网络字节顺序(network byte order)(大端字节顺序)(big endian)存放,即使主机字节顺序是小端法(small endian)。
Unix 下有

#include <netinet/in.h>unsigned long int htonl(unsigned long int hostlong);unsigned short int htons(unsigned short int hostshort);// host to networkunsigned long int ntohl(unsigned long int netlong);unsigned short int ntohs(unsigned short int netshort);// network to host

为了方便记忆,IP有点分十进制表示法,每个字节使用十进制表示并用句号分割开。转换函数如下:

#include <arpa/inet.h>int inet_aton(const char *cp, struct in_addr *inp);// application to networkchar *inet_ntoa(struct in_addr in);// network to application

练习

练习11.2

编写程序hex2dd.c,它将十六进制参数转换为点分十进制串并打印出结果。例如

unix> ./hex2dd 0x8002c2f2128.2.194.242

解:

#include <stdio.h>#include <arpa/inet.h>#include <string.h>#include <netinet/in.h>const char *useage = "useage: %s <hex IP like 0x7f000001>\n\ttranslate hex(network) to dd(application).\n";int table[255];void initTable(){    memset(table,-1,sizeof(table));    table['0'] = 0;    table['1'] = 1;    table['2'] = 2;    table['3'] = 3;    table['4'] = 4;    table['5'] = 5;    table['6'] = 6;    table['7'] = 7;    table['8'] = 8;    table['9'] = 9;    table['a'] = table['A'] = 10;    table['b'] = table['B'] = 11;    table['c'] = table['C'] = 12;    table['d'] = table['D'] = 13;    table['e'] = table['E'] = 14;    table['f'] = table['F'] = 15;}int readArg(int n,char *s[],struct in_addr *in){    int i,j;    in -> s_addr = 0;    if(n != 2)        return 0;    else{        n = strlen(s[1]);        if( (n < 2 || n > 10)||(s[1][0] != '0' &&                 (s[1][1]!= 'x' || s[1][1] != 'X')))            return 0;        else            for(i = ( n - 3 ) * 4,j = 2;j < n;i -= 4 , j++){                if(table[s[1][j]] == -1)                    return 0;                in -> s_addr |= table[ s[1][j] ]<<i;            }    }    in -> s_addr = ntohl(in -> s_addr);    return 1;}int main(int argc,char *argv[]){    initTable();    struct in_addr ip;    if(readArg(argc,argv,&ip))        printf("%s\n",inet_ntoa(ip));    else        fprintf(stderr,useage,argv[0]);    return 0;}

练习11.3

编写程序 dd2hex.c,它将它的点分十进制参数转换为十六进制数并打印出结果。例如

unix> ./dd2hex 128.2.194.2420x8002c2f2

解:

#include <arpa/inet.h>#include <netinet/in.h>#include <string.h>#include <stdio.h>const char *useage = "useage: %s 128.2.194.242\n\ttranslate dd(application) to hex(network).";int main(int argc,char *argv[]){    if(argc != 2){        fprintf(stderr,useage,argv[0]);        return -1;    }    struct in_addr ip;    if(!inet_aton(argv[1],&ip)){        fprintf(stderr,useage,argv[0]);        return -1;    }    printf("0x%x\n",htonl(ip.s_addr));    return 0;}
0 0
原创粉丝点击