1.1.IPv4套接口地址结构
也称为“网际套接字地址结构”,它以“sockaddr_in"命名
#include <netinet/in.h>
struct sockaddr_in{
unit8_t sin_len; //整个sockaddr_in结构体长度
sa_family_t sin_family; //指定地址家族,AF_INET:ipv协议
in_port_t sin_port; //端口16bits
struct in_addr sin_addr; //ipv4地址 32bits
char sin_zero[8];
};
struct in_addr{
in_addr_t s_addr;
};
此结构表示一个32位ipv4地址
in_addr_t一般为32位的 unsigned int,为网络字节序,即该无符号数采用大端字节序。
其中每8位表示一个ip地址中的一个数值。
打印时可以调用 net_ntoa() 函数将其转换为 char* 类型。
头文件为: #include <arpa/inet.h>
inet_ntoa()函数用于将一个十进制网络字节序转换为点分十进制ip格式的字符串。
函数原型为:
char* inet_ntoa(struct in_addr in);
1.2.以下为任何协议的套接口:
struct sockaddr{
unit8_t sin_len; //整个结构体长度
sa_family_t sin_family; //该地址协议家族
char sa_data[14]; //由sin_family决定它的形式
};
通常我们在linux下先建立ipv4形式的 struct sockaddr_in 结构体,然后再强制转换为通用形式。
2.字节序
以下为字节序的转换函数,包含的头文件为:
#include <arpa/inet.h>
1 uint32_t htonl(uint32_t hostlong);
2 uint16_t htons(uint16_t hostshort);
3 uint32_t ntohl(uint32_t netlong);
4 uint16_t ntohs(uint16_t netshort);
5 h:host n:network s:short l:long
大端字节序(BigEndian):
就是高字节(MSB)在前,内存存储体现上,数据的高位更加靠近内存低地址。
数据高位存储在内存低地址
小端字节序(Little-Endian):
就是低字节(LSB)在前,内存存储体现上,数据的低位更加靠近内存低地址。
数据高位存储在内存高地址
编写程序测试本机是大端字节序还是小端:
#include <stdio.h>
#include <arpa/inet.h>
int main(){
unsigned int x = 0x12345678; //4bytes
unsigned char* p = (unsigned char*)&x; //1byte
printf("%0x%0x%0x%0x\n",p[0],p[1],p[2],p[3]);
//主机转换为网络,网络为大端字节序
unsigned int y = htonl(x);
p = (unsigned char*)&y;
printf("%0x%0x%0x%0x\n",p[0],p[1],p[2],p[3]);
return 0;
}
ubuntu下运行结果
本机将高位数据12存储在内存地址高位,所以是小端字节序 ,
而转换后为大端字节序,高位数据12被存储在内存地址低位。
3地址转换函数
int inet_aton(const char* cp,struct in_addr* inp);
//将一个字符串IP地址转换为一个32位的网络序列IP地址
in_addr_t inet_addr(const char* cp);
//将点分十进制转换成32位整数
char* inet_ntoa(strcut in_addr in);
//将地址结构转换成点分十进制的字符串形式
代码测试:
#include <stdio.h>
#include <arpa/inet.h>
int main(){
unsigned long addr = inet_addr("192.168.1.100");
printf("addr = %u\n",ntohl(addr));
//网络地址转换为本机地址(大小端)打印
struct in_addr ipaddr; //ipv4地址结构
ipaddr.s_addr = addr; //结构成员为32位无符号整型
printf("%s\n",inet_ntoa(ipaddr));
/*
*char* p = inet_ntoa(ipaddr);
*printf("%s\n",p);
*/
return 0;
}
运行结果: