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 network
unsigned 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 network
char *inet_ntoa(struct in_addr in);
// network to application
练习
练习11.2
编写程序hex2dd.c,它将十六进制参数转换为点分十进制串并打印出结果。例如
unix> ./hex2dd 0x8002c2f2
128.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.242
0x8002c2f2
解:
#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;
}