P14 字节序
小端模式:低位字节数据存储在低地址
大端模式:高位字节数据存储在低地址
int a=0x12345 (低地址存低位就是小端模式,一般是host模式,反之就是大端模式,一般就是网络字节序)
靠近0x是高字节序,远离0x的是低字节序
如何判断主机的字节序
1 #include<stdio.h> 2 union un{ 3 int a; 4 char b; 5 }; //共用体和结构体的区别好好看一下吧 6 7 int main(int argc, char **argv) 8 { 9 union un myun; 10 //int型4个字节,32位,用16进制刚好8位 11 myun.a = 0x12345678; 12 13 printf("a = %#x\n", myun.a); 14 printf("b = %#x\n", myun.b); 15 if(myun.b == 0x78) 16 { 17 printf("小端"); 18 } 19 else 20 { 21 printf("大端"); 22 } 23 return 0; 24 }
P15字节序转换函数
总共4个函数:主机转换网络,网络转换主机
htonl 主机转换网络---》小端转大端
htons
ntohl 网络字节序转主机字节序
ntohs
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostint32)
功能:将32位主机字节序转换成网络字节序
参数:32位字节序数据
返回值:成功返回网络字节序的值
uint32_t htons(uint32_t hostint32)
功能:
参数
返回值:
uint32_t ntohl(uint32_t hostint32)
功能:
参数
返回值:
uint32_t ntohs(uint32_t hostint32)
功能:
参数
返回值:
1 #include <stdio.h>
2 #include <arpa/inet.h>
3 int main(int argc, char **argv)
4 {
5 int a = 0x12345678;
6 short b = 0x01234;
7 printf("%#x\n", htonl(a));//从小端模式变大端,主机变网络
8 printf("%#x\n", htons(b));
9 return 0;
10 }
结果
0x78563412
0x3412
P16 地址转换函数include<arpa/inet.h>
人为输入的ip地址是字符串,计算机中使用的32位整型数据,所以需要转换
(1)int inet_pton(int family, const char * strptr, void *addrptr)
功能:将点分十进制数字符串转换成32位无符号整数
参数:
family 协议族 AF_INET(ipv4)
strptr 点分十进制数串
addrptr 32位无符号整数的地址
返回值:成功返回1,
字符串是如何存储的呢?每个字节存储一个数字,
2的8次方 - 1 == 255(刚刚好对应无符号整型的数)
(2)整型数据转换成字符串格式ip地址
const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t len)
功能:将32位无符号整数转换成点分十进制字符串
参数:
family 协议族 AF_INET(ipv4)
addrptr 32位无符号整数的地址
strptr 点分十进制数串
len 的宏定义16
成功返回字符串地址,失败返回NULL
如何用写一个整型数据,表示为IP地址,因为ip地址时有范围的,所以整型数也是有范围的,这个整型数如何给出来呢????
unsigned char ip_int[4]={192,168,1,1};只需要把ip_int当成整型数看待即可!!!!
1 #include<stdio.h>
2 #include<arpa/inet.h>
3 int main(int argc, char **argv)
4 {
5 char ip_str[] = "192.168.3.103";
6 unsigned int ip_int = 0;
7 unsigned char *ip_p = NULL;
8 inet_pton(AF_INET, ip_str, &ip_int);
9 printf("ip_uint = %d\n", ip_int);
10
11 ip_p = (char *)&ip_int;
12 printf("ip_unit =%d, %d, %d, %d\n", *ip_p, *(ip_p + 1), *(ip_p + 2), *(ip_p + 3));
13 return 0;
14 }
结果
ip_uint = 1728293056
ip_unit =192, 168, 3, 103
| 0|0 |0 |0 |0 |0 |0 |0 | 以直接位单位
也就是说192.186.3.103这个字符串在转换成整型数时,192占整型的第0-7位,用字符形式读取的时候,取0-7位
#include<stdio.h>
#include<arpa/inet.h>
int main(int argc, char **argv)
{
char ip_str[16]="";
unsigned char ip_int[] = {192,168,3,103};//整型数
inet_ntop(AF_INET,&ip_int, ip_str, 16);
printf("ip_s = %s\n, ip_str");
return 0;
}//字符串ip地址转换成点分十进制
拓展两个IPv4使用更加方便的函数,只能在v4中使用
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int_addr_t inet_addr (const char *cp);
功能:将点分十进制ip地址转化为整型数据
参数:cp:点分十进制的IP地址
返回值:成功返回整型数据
char *inet_ntoa(struct in_addr in)
功能:将整型数据转化为点分十进制的ip地址
参数:in:保存ip地址的结构体
成功返回点分十进制的ip地址
常见的几个函数
inet_addr、inet_ntoa 只能用在ipV4当中
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
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);