字节序转换函数
#include <arpa/inet.h>
// 转换端口
uint16_t htons(uint16_t hostshort); // 主机字节序->网络字节序
uint16_t ntohs(uint16_t netshort); // 网络字节序->主机字节序
// 转换IP
uint32_t htonl(uint32_t hostlong);
uint32_t ntohl(uint32_t netlong);
通用socket地址
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
};
typedef unsigned short int sa_family_t; // 2字节的地址族
地址族(address family)与协议族(protocol family)对应
协议族 | 地址族 | 描述 |
---|---|---|
PF_UNIX | AF_UNIX | UNIX本地域协议族 |
PF_INET | AF_INET | TCP/IPv4协议族 |
PF_INET6 | AF_INET6 | TCP/IPv6协议族 |
专用socket地址
struct sockaddr_in {
sa_family_t sin_family; // 地址族
in_port_t sin_port; // 端口号
struct in_addr sin_addr; // IPv4地址结构体
};
struct in_addr {
in_addr_t s_addr; // IPv4地址
};
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef uint16_t in_port_t; // 2字节的端口号
typedef uint32_t in_addr_t; // 4字节的IPv4地址
IP地址转换
字符串IP与整数的转换
in_addr_t inet_addr(const char *cp);
// 将点分十进制IPv4地址转换为网络字节序的整数返回
int inet_aton(const char *cp, struct in_addr *inp);
// 将点分十进制IIPv4的地址cp转换为网络字节序的整数inp,成功返回1,失败返回0,设置错误号
char *inet_ntoa(struct in_addr in);
// 网络字节序整数转换为点分十进制字符串返回
上面这些比较旧,只适用于IPv4地址,下面这些新的转换函数同时适用于IPv4和IPv6
#include <arpa/inet.h>
// p: 点分十进制字符串,n: 网络字节序整数
int inet_pton(int af, const char *src, void *dst);
// 点分十进制字符串转换为网络字节序整数
- af: 地址族 AF_INET/AF_INET6
- src: 需要转换的点分十进制字符串
- dst: 传出参数,转换后的整数
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
// 整数转换为点分十进制的IP地址字符串
- af: 地址族
- src: 要转换的ip整数地址
- dst: 转换后的ip字符串
- size: 第三个参数的大小
// 返回转换后的字符串,和dst一样
示例
#include <arpa/inet.h>
#include <stdio.h>
int main() {
char buf[] = "192.168.1.4";
unsigned int num = 0;
// 将点分十进制字符串转换整数
inet_pton(AF_INET, buf, &num);
unsigned char *p = (unsigned char *)#
for (int i = 0; i < 4; i++) {
printf("%d ", *(p + i));
}
printf("\n");
// 整数IP转换为点分十进制字符串
char ip[16] = "";
const char *str = inet_ntop(AF_INET, &num, ip, 16);
printf("ip: %s\n", ip);
printf("str: %s\n", str);
return 0;
}
192 168 1 4
ip: 192.168.1.4
str: 192.168.1.4