最近在搞VoIP,在阅读别人的源码时发现了IP地址转换过程中的问题,写下笔记。
经验如下:
1、点分十进制IP,输入时以字符串的形式读入;
2、正统的IP地址存储用 struct in_addr 定义数据结构进行存储;
3、点分十进制IP转化为无符号长整形IP用inet_addr()函数;点分十进制转化为struct in_addr结构的网络序IP用inet_aton()反向转化用inet_ntoa()函数,linux下需要包含两个头文件:
#include<arpa/inet.h>
#include<netinet/in.h>
4、无符号长整形IP要存储到in_addr结构体中,可以用memcpy(&addr1,&ulip,4);其中addr1是struct in_addr 结构体,ulip是无符号长整形,inet_ntoa()函数的形参必须是in_addr结构体数组,返回值为字符指针。
5、无符号长整形主机序转网络序用htonl()函数,反向用ntohl()函数;这两个函数遵循负负得正规律。短整型网络字节序转换用htons()和ntohs();
6、in_addr结构体定义如下:
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
};
/*************************************************************************
> File Name: ipStringTest.c
> Author: SunHao
> Mail: sunhaoyn@qq.com
> Created Time: 2014年11月26日 星期三 15时32分01秒
************************************************************************/
#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
int main()
{
char ipStr[50];
unsigned long ip;
unsigned long ulip;
struct in_addr addr1;
while(1)
{
printf("input ip addr:\n");
scanf("%s",ipStr);
ip=inet_addr(ipStr);
printf ("your input ip is:\t%s\n",ipStr);
ulip=ip;
memcpy(&addr1,&ulip,4);
printf("the inet_addr ip:\t\t%x\t%s\n",ulip,inet_ntoa(addr1));
ulip=htonl(ip);
memcpy(&addr1,&ulip,4);
printf("the inet_addr htonl ip:\t\t%x\t%s\n",ulip,inet_ntoa(addr1));
ulip=ntohl(ulip);
memcpy(&addr1,&ulip,4);
printf("the inet_addr ntohl ip:\t\t%x\t%s\n",ulip,inet_ntoa(addr1));
ulip=htonl(htonl(ip));
memcpy(&addr1,&ulip,4);
printf("the inet_addr htonl*2 ip:\t%x\t%s\n",ulip,inet_ntoa(addr1));
}
}
运行结果如下:
input ip addr:
172.16.15.249
your input ip is: 172.16.15.249
the inet_addr ip: f90f10ac 172.16.15.249
the inet_addr htonl ip: ac100ff9 249.15.16.172
the inet_addr ntohl ip: f90f10ac 172.16.15.249
the inet_addr htonl*2 ip: f90f10ac 172.16.15.249
input ip addr: