之前遇到过要自己实现inet_aton和inet_ntoa函数功能的问题,这里总结一下。
1 基本知识
网络字节序是大端模式,那么内存中的低地址存放的是数据的高位,内存中的高地址存放的是数据的低位。 inet_aton是将IPv4地址(点分法)转换成对应的十进制整数;而inet_ntoa是将十进制整数转换成对应的IPv4地址(点分法)。
2 完整代码
#include
#include
#include "print.h"
#define IP_ADRESS "192.168.1.177"
/*
* 将IPv4地址(点分法)转换成对应的十进制整数
* 原函数声明:
* int inet_aton(const char *cp, struct in_addr *inp);
*/
unsigned int __inet_aton( const char *c_ipaddr )
{
unsigned int u_ipaddr = 0;
unsigned int u_tmp = 0;
char c;
int i_base = 10;
int i_shift = 0;
int i_recycle = 0;
c = *c_ipaddr;
while( 1 )
{
u_tmp = 0;
while( 1 )
{
//如果是数字
if( isdigit(c) )
{
u_tmp = (u_tmp * i_base) + (c - 0x30);
c = *++c_ipaddr;
}
else
{
//如果不是数字而是.符号,说明.符号前面的数据已经处理完毕
break;
}
}
//字节移位,注意网络字节序是大端模式
i_shift = 8*i_recycle++;
u_tmp <<= i_shift;
u_ipaddr += u_tmp;
//对点(.)符号的处理
if( c == '.' )
{
c = *++c_ipaddr;
}
else
{
//如果是其它符号(例如结束符 等)则跳出整个循环
break;
}
}
//检查是否包含非结束符、空格等符号,是则返回0
if( c != ' ' && ( !isspace(c) ) )
goto ret_0;
return u_ipaddr;
ret_0:
return (0);
}
/**
* 将十进制整数转换成对应的IPv4地址(点分法),其中由于网络字节序是大端表示,所以第一个字节对应的是整数的低位byte[0]
* 原函数声明:
* int inet_aton(const char *cp, struct in_addr *inp);
*/
static char buffer[16];
char * __inet_ntoa( unsigned int in )
{
unsigned char *bytes = (unsigned char *) ∈
snprintf( buffer, sizeof (buffer), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] );
return buffer;
}
int main( int argc, char **argv )
{
PRINT( "IP_ADRESS[%s] ==> [%lu].", IP_ADRESS, __inet_aton( IP_ADRESS ) );
PRINT( "[%lu]=[0x%x].", __inet_aton( IP_ADRESS ), __inet_aton( IP_ADRESS ) );
PRINT( "Network orders[%lu] ==> [%s].", __inet_aton( IP_ADRESS ), __inet_ntoa(__inet_aton( IP_ADRESS )) );
return 0;
}
3 编译执行
使用《Linux C/C++工程中可生成ELF、动/静态库文件的通用Makefile》一文中的Makefile文件进行程序编译(当然也可以使用命令进行编译gcc network_selfdefine.c -o network_selfdefine),接着执行该程序,得到如下图所示的结果:
自己实现inet_aton和inet_ntoa函数功能
需要说明的是从第87行输出的[2969675968]=[0xb101a8c0].可以看出,低字节的0xC0(即192)由于网络字节序大端模式的关系存放在内存中的高位,高字节的0xB1(即177)存放在内存中的低位。
4 附录
关于inet_aton的man说明:
[vfhky@typecodes xlei]$ man inet_aton
INET(3) Linux Programmer's Manual INET(3)
NAME
inet_aton, inet_addr, inet_network, inet_ntoa, inet_makeaddr, inet_lnaof,
inet_netof - Internet address manipulation routines
SYNOPSIS
#include
#include
#include
int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);
in_addr_t inet_network(const char *cp);
char *inet_ntoa(struct in_addr in);
struct in_addr inet_makeaddr(int net, int host);
in_addr_t inet_lnaof(struct in_addr in);
in_addr_t inet_netof(struct in_addr in);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
inet_aton(), inet_ntoa(): _BSD_SOURCE || _SVID_SOURCE
DESCRIPTION
inet_aton() converts the Internet host address cp from the IPv4 numbers-and-dots
notation into binary form (in network byte order) and stores it in the structure
that inp points to. inet_aton() returns nonzero if the address is valid, zero if
not.
关于inet_aton的man说明:
[vfhky@typecodes ~]$ man inet_ntoa
INET(3) Linux Programmer's Manual INET(3)
NAME
inet_aton, inet_addr, inet_network, inet_ntoa, inet_makeaddr, inet_lnaof,
inet_netof - Internet address manipulation routines
SYNOPSIS
#include
#include
#include
int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);
in_addr_t inet_network(const char *cp);
char *inet_ntoa(struct in_addr in);
struct in_addr inet_makeaddr(int net, int host);
in_addr_t inet_lnaof(struct in_addr in);
in_addr_t inet_netof(struct in_addr in);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
inet_aton(), inet_ntoa(): _BSD_SOURCE || _SVID_SOURCE
DESCRIPTION
inet_aton() converts the Internet host address cp from the IPv4 numbers-and-dots
notation into binary form (in network byte order) and stores it in the structure
that inp points to. inet_aton() returns nonzero if the address is valid, zero if
not.
茶杯头甜蜜终章dlc 官方手机版v1.0.0.3
下载火柴人传说暗影格斗内置菜单 最新版v3.0.1
下载荒野乱斗测试服 安卓版v61.10.3
下载荒野乱斗彩虹服 安卓版v61.10.3
下载寒霜启示录 安卓版v1.25.10
寒霜启示录是一款生存模拟游戏,不少玩家可能对于末日都有着自己
末日城堡免广告版 安卓最新版v0.7.1
末日城堡免广告版是一款非常好玩的模拟经营类游戏,内部可以不看
甜蜜人生模拟器 最新版v1.4.5
甜蜜人生模拟器是一款非常好玩的模拟恋爱手游,玩家在这里能够对
武器锻造师内置功能菜单 v10.4
武器锻造师内置菜单版是游戏的破解版本,在该版本中为玩家提供了
开放空间overfield 安卓版v1.0.5
开放空间Overfield是一款箱庭养成经营手游,让你在广阔