1 接口
1.1 转换操作
转换操作主要分为三类:字节序转换操作、IP地址转换操作和主机名转换操作。
1.1.1 字节序转换操作
1.1.2 IP地址转换操作
IPv4地址结构:
struct in_addr {
in_addr_t s_addr;
};
IPv4地址类型:
typedef unsigned int in_addr_t;
套接字地址结构:
struct sockaddr {
unsigned short sa_family; // 套接字地址簇类型,为AF_INET
char sa_data[14]; // 套接字地址数据(14位的协议地址)
};
IPv4套接字地址结构:
struct sockaddr_in{
short sin_family; // 套接字地址簇类型,为AF_INET
unsigned short sin_port; // 端口号,网络字节序
struct in_addr sin_addr; // IP地址,网络字节序
unsigned char sin_zero[8];// 填充字节
};
sin_zero[8]用来保证结构体struct sockaddr_in的大小和结构体struct sockaddr的大小相等。
IPv6套接字地址结构:
struct sockaddr_in6{
uint8_t sin6_len; //IPv6 为固定的24 字节长度
sa_family_t sin6_family; //套接字地址簇类型,为AF_INET6
in_port_t sin6_port; //16 位端口号,网络字节序
uint32_t sin6_flowinfo; //32 位流标签
struct in6_addr sin6_addr; //128 位IP地址
}
1.2 ipv4专用
1.2.1 点分十进制数串转网络字节序长整型
推荐方式:
int inet_aton(const char *string, struct in_addr*addr);
参数说明:
参数 | 含义 |
---|---|
string | 点分十进制IP地址字符串 |
addr | 网络字节序长整型IP地址 |
返回值说明:
返回值 | 含义 |
---|---|
0 | 成功 |
非0 | 失败 |
示例:
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main(int argc,char* argv[]){
if(2 != argc){
printf("usage:%s <ip>\n",argv[0]);
return 1;
}
struct in_addr addr;
int res = inet_aton(argv[1],&addr);
if(0 == res){
perror("inet_aton error");
return 1;
}
printf("res:%d\n%s = 0x%08x",res,argv[1],addr);
return 0;
}
旧方式:
in_addr_t inet_addr(const char* string);
参数说明:
参数 | 含义 |
---|---|
string | 点分十进制IP地址字符串 |
返回值说明:
返回值 | 含义 |
---|---|
INADDR_NONE | 失败 |
非INADDR_NONE | 网络字节序长整型IP地址 |
示例:
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main(int argc,char* argv[]){
if(2 != argc){
printf("usage:%s <ip>\n",argv[0]);
return 1;
}
in_addr_t addr = inet_addr(argv[1]);
if(INADDR_NONE == addr){
perror("inet_addr error");
return 1;
}
printf("%s = 0x%08x",argv[1],addr);
return 0;
}
1.2.2网络字节序长整型转点分十进制数串
char* inet_ntoa(struct in_addr addr);
参数说明:
参数 | 含义 |
---|---|
addr | 网络字节序长整型IP地址 |
返回值说明:
返回值 | 含义 |
---|---|
非NULL | 点分十进制IP地址字符串 |
NULL | 失败 |
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main(int argc,char* argv[]){
if(2 != argc){
printf("usage:%s <num>\n",argv[0]);
return 1;
}
struct in_addr addr;
addr.s_addr = strtol(argv[1],NULL,16);
char* ip = inet_ntoa(addr);
if(NULL == ip){
perror("inet_ntoa error");
return 1;
}
printf("0x%x = %s",addr.s_addr,ip);
return 0;
}
1.3 IPv4/IPv6通用(推荐)
1.3.1 点分十进制数串转网络字节序长整型
int inet_pton(int af, const char *src, void *dst);
参数说明:
参数 | 含义 |
---|---|
af | 地址族:AF_INET/AF_INET6 |
src | 点分十进制IP地址字符串 |
dst | 网络字节序长整型IP地址 |
返回值说明:
返回值 | 含义 |
---|---|
<0 | 失败 |
0 | af和src格式不对 |
示例:
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
int main(int argc,char* argv[]){
char ip[INET_ADDRSTRLEN];
if(argc == 1){
scanf("%s",ip);
}else if(2 != argc){
printf("usage:%s <ip>\n",argv[0]);
return 1;
}
struct in_addr addr;
memset(&addr,0,sizeof(addr));
if(1 != inet_pton(AF_INET,(argc == 1?ip:argv[1]),&addr)){
perror("inet_pton err");
return 1;
}
printf("%x\n",addr.s_addr);
}
1.3.2 网络字节序长整型转点分十进制数串
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
参数说明:
参数 | 含义 |
---|---|
af | 地址族:AF_INET/AF_INET6 |
src | 网络字节序长整型IP地址 |
dst | 点分十进制IP地址字符串 |
cnt | 缓存区dst的大小 |
返回值说明:
返回值 | 含义 |
---|---|
NULL | 失败 |
非NULL | dst指针 |
示例:
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
int main(int argc,char* argv[]){
if(2 != argc){
printf("usage:%s <dec num>\n",argv[0]);
return 1;
}
struct in_addr addr;
memset(&addr,0,sizeof(addr));
addr.s_addr = strtol(argv[1],NULL,16);
char ip[INET_ADDRSTRLEN];
if(NULL == inet_ntop(AF_INET,&addr,ip,sizeof(ip))){
perror("inet_ntop err");
return 1;
}
printf("%s\n",ip);
}
示例:
#include <iostream>
#include <arpa/inet.h>
using namespace std;
int main(){
cout << sizeof(short) << endl;
short s = 0x1234;
cout << hex << s << endl;
cout << hex << htons(s) << endl;
cout << sizeof(long) << endl;
int l = 0x12345678;
cout << hex << l << e