IP地址本地字节序的转换函数有以下几种:
1、uint32_t htonl(uint32_t hostlong); //一般不用来转换ip地址
这个函数是int转int型,而我们习惯用的ip的是点分十进制的字符串。
用起来不方便,(因为,需要先将点分十进制-转换成uint32_t,然后再调用htonl()函数)
所以,此函数多数用来将32位(4字节整型)进行字节序转换。
ps:
INADDR_ANY,当不指定ip地址时,可以直接用该宏定义,最简单。
addr.sin_addr.s_addr = htonl(INADDR_ANY);//自动获取当前网卡的有效ip地址
2、int inet_pton(int af,const char*src,void*dst); //经常用这个函数点分十进制字符串ip转换为网络字节序。
//示例
char *ip ="192.168.1.1";
char *port = "8000";
struct sockaddr_in addr;
addr.sinfamily = AF_INET; // 或AFINET6
addr.sin_port = htons(atoi(port));
inet_pton(AF_INET,ip,&addr.sin_addr);
同样,如果需要从网络字节序转换到主机字节序
使用 const char* inet_ntop(int af,const void *src,char *dst,socklen_t size);------->直接会转换成点分十进制字符串。
dst为转换后的点分十进制字符串;size为dst的大小
//示例
char str[sizeof(in_addr)];
ptr = inet_ntop(AF_INET, &foo.sin_addr, str, sizeof(str));
由附录5中可以看出,inet_ntop的第二个参数为指向 struct in_addr的结构体指针。
3、inet_addr()函数 //已经废弃,不推荐使用
//示例
char *ip ="192.168.1.1";
char *port = "8000";
struct sockaddr_in addr;
addr.sinfamily = AF_INET; // 或AFINET6
addr.sin_port = htons(atoi(port));
addr.sin_addr.s_addr = inet_addr(ip);
4、总结:共有以上三种方式来将IP地址进行网络字节序转换。
写程序时,一般选择前2种形式:
1)addr.sin_addr.s_addr = htonl(INADDR_ANY);
2)inet_pton(AF_INET,ip,&addr.sin_addr);
注意:inet_pton的第3个参数带入的是in_addr结构体指针,而不是&addr.sin_addr.s_addr,因为从5附录中可以看出,dst必须是sizeof(struct in_addr)bytes long的,所以,推测该参数应为&addr.sin_addr
5、附录:
struct sockaddr_in{
sa_family_t sin_family;//地址族协议
in_port_t sin_port;//端口号
struct in_addr sin_addr;//ip地址
};
struct in_addr{
uint32_t s_addr;
};