网络字节序和IP地址详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/daaikuaichuan/article/details/83061117

一、网络字节序

  字节序是指多字节数据的存储顺序,在设计计算机系统的时候,有两种处理内存中数据的方法:大端格式、小端格式。

  • 小端格式(Little-Endian):将低位字节数据存储在低地址;
  • 大端格式(Big-Endian):将高位字节数据存储在低地址。
    在这里插入图片描述

  举个简单的例子,对于整形 0x12345678,它在大端格式和小端格式的系统中,分别如下图所示的方式存放:
在这里插入图片描述

【下面例子为确定主机的字节序】:

#include <stdio.h>  
int main(int argc, charchar *argv[])  
{  
    unsigned int a = 0x12345678;  
    unsigned char *p = (unsigned char *)&a; //只取一个字节  
    if(0x12 == *p){  
        printf("Big-Endian\n");  
    }else if(0x78 == *p){  
        printf("Little-Endian\n");  
    }  
    return 0;  
}  

  网络字节序定义:收到的第一个字节被当作高位看待,这就要求发送端发送的第一个字节应当是高位。而在发送端发送数据时,发送的第一个字节是该数字在内存中起始地址对应的字节。可见多字节数值在发送前,在内存中数值应该以大端法存放。

  所以,网络协议指定了通讯字节序:大端。只有在多字节数据处理时才需要考虑字节序,运行在同一台计算机上的进程相互通信时,一般不用考虑字节序,异构计算机之间通讯,需要转换自己的字节序为网络字节。主机字节序是小端,所以才需要进行字节序转换。


二、字节序转换函数

#include <arpa/inet.h>
// 将 32位主机字节序数据转换成网络字节序数据
//(h:host, n:net,l:long)
uint32_t htonl(uint32_t hostint32);
// 将 16 位主机字节序数据转换成网络字节序数据
uint16_t htons(uint16_t hostint16);
// 将 32 位网络字节序数据转换成主机字节序数据
uint32_t ntohl(uint32_t netint32);
// 将 16 位网络字节序数据转换成主机字节序数据
uint16_t ntohs(uint16_t netint16);

三、IP地址详解

1、IP地址的概念

  IP地址分为网络IP和主机IP:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • A类地址第一字节为网络ID,后三个字节为主机ID,范围是1.0.0.1—126.155.255.254; 默认子网掩码:255.0.0.0;
  • B类地址第一二字节为网络ID,后两个字节为主机ID,范围是128.0.0.1—191.255.255.254; 默认子网掩码:255.255.0.0;
  • C类地址前三个字节为网络ID,最后一个字节为主机ID,范围是192.0.0.1—223.255.255.254;默认子网掩码:255.255.255.0;
  • D类地址用于组播,前四位为1110,范围是224.0.0.1—239.255.255.254;
  • E类地址用于研究,前五位为11110,范围是240.0.0.1—255.255.255.254。

2、IP地址的两种表示方法:整数和点分十进制

点分十进制->整数:点分十进制->十六进制->十进制(整数)。

整数->点分十进制:十进制(整数)->十六进制->每个字节转换为十进制(整数)。

3、判断IP地址是否合法

  • IP的格式为:(1~255).(0~255).(0~255).(0~255)

  • 以小数点开头为非法IP,如:.x.x.x.或者.x.x.xx;

  • 以小数点结尾为非法IP,如:x.x.x.x.;

  • 输入带0开头为非法IP,如:0x.0xx.0x.00x。


四、IP地址转换

1、将点分十进制数串转换成 32 位无符号整数

#include <arpa/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr);
  • 功能: 将点分十进制数串转换成 32 位无符号整数。
  • 参数:
    • family:协议族( AF_INET、AF_INET6、PF_PACKET 等 ),常用 AF_INET;
    • strptr:点分十进制数串;
    • addrptr:32 位无符号整数的地址。
  • 返回值: 成功返回 1 ,失败返回其它。
#include <stdio.h>  
#include <arpa/inet.h>  
int main()  
{  
    char ip_str[]="172.20.223.75";  
    unsigned int ip_uint = 0;  
    unsigned charchar *ip_p = NULL;  
  
    inet_pton(AF_INET,ip_str,&ip_uint);  
    printf("in_uint = %d\n",ip_uint);  
      
    ip_p = (charchar *)&ip_uint;  
    printf("in_uint = %d,%d,%d,%d\n",*ip_p,
    	*(ip_p+1),*(ip_p+2),*(ip_p+3));  
  
    return 0;  
} 

1、将点分十进制数串转换成 32 位无符号整数

#include <arpa/inet.h>
const char *inet_ntop( int family, const void *addrptr, 
						char *strptr, size_t len );
  • 功能: 将 32 位无符号整数转换成点分十进制数串。
  • 参数:
    • family:协议族( AF_INET、AF_INET6、PF_PACKET 等 ),常用 AF_INET;
    • addrptr:32 位无符号整数;
    • strptr:点分十进制数串;
    • len:strptr 缓存区长度;
      • #define INET_ADDRSTRLEN 16 // for ipv4
      • #define INET6_ADDRSTRLEN 46 // for ipv6
  • 返回值: 成功:则返回字符串的首地址,失败:返回 NULL

转自:https://blog.csdn.net/lianghe_work/article/details/45170285
https://blog.csdn.net/Esther_Heesch/article/details/51476811
https://blog.csdn.net/weixin_36525275/article/details/79456065
https://blog.csdn.net/u014259820/article/details/78833196

猜你喜欢

转载自blog.csdn.net/daaikuaichuan/article/details/83061117