Linux网络编程笔记(二)字节序、地址结构和IPv4地址族

字节序简介

不同系统字节存储顺序不同,有的是高位在前,有的是低位在前:
在这里插入图片描述
其中,MSB代表最重要位,LSB代表最不重要位。
上图中第一个字节序称为大端字节序,因为高位在前;下面的字节序称为小端字节序,因为低位在前。
需要注意的是,网络协议使用网络字节序即大端字节序,所以编程时,主机字节序和网络字节序可能会要合理转换。

字节序转换函数

由于网络字节序和主机字节序有可能不同,所以对于内部字节表示顺序和网络字节顺序不同的机器,就一定要对数据进行转换。

uint32_t htonl(uint32_t hostlong); //将一个32位整数由主机字节序转换成网络字节序
uint16_t htons(uint16_t hostshort); //将一个16位整数由主机字节序转换成网络字节序
uint32_t ntohl(uint32_t netlong); //将一个32位整数由网络字节序转换成主机字节序
uint16_t ntohs(uint16_t netshort); //将一个16位整数由网络字节序转换成主机字节序

网络地址结构

网络地址结构有两种:通用地址结构和因特网地址结构。
由于通用地址结构多种信息混合在一起,用起来较繁杂,所以一般选择因特网地址结构

通用地址结构

通用地址结构如下:

#include<sys/socket.h>
struct sockaddr{
	unsigned short sa_family; /*Inetrnet地址族,AF_XXX*/
	char sa_data[14];		 /*14 bytes的协议地址*/
};

参数:

  • sa_family:一般来说,IPV4使用AF_INET。
  • sa_data:包含了一些远程电脑的地址、端口和套接字的数目,它里面的数据是杂溶在一起的。

因特网地址结构

因特网地址结构如下:

struct in_addr{
	in_addr_t s_addr /*ipv4地址*/
};
struct sockaddr_in{
	short int sin_family; /*Internet地址族如AF_INET(主机字节序)*/
	unsigned short int sin_port; /*端口号,16位值(网络字节序)*/
	struct in_addr sin_addr;	/*Internet地址,32位IPv4地址(网络字节序)*/
	unsigned char sin_zero[8];	/*添0(为了格式对齐的填充位)*/
};

IPv4地址族和字符地址间的转换

#include<arpa/inet.h>
const char *inet_ntop(int domain,const void *restrict addr,char *restrict str,socklen_t size);
	//返回:成功返回地址字符串指针,出错返回NULL
	//功能:网络字节序转换成点分十进制
int inet_pton(int domain,const char *restrict str,void *restrict addr);
	//返回:成功返回1,无效格式返回0,出错返回-1
	//功能:点分十进制转换成网络字节序

参数:

  • domain:Internet地址族,如AF_INET
  • addr:Internet地址,32位IPv4地址(网络字节序)
  • str:地址字符串(点分十进制)指针
  • size:地址字符串大小

示例

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>

int main(int argc,char *argv[]){
        struct sockaddr_in sin;
        char buf[16];
        memset(&sin,0,sizeof(sin)); //内存清零
        sin.sin_family=AF_INET; //填写Internet地址族
        sin.sin_port=htons((short)3001); //填写端口号(网络字节序)

        if(inet_pton(AF_INET,"192.168.2.1",&sin.sin_addr.s_addr)<=0)
                printf("pton error!\n");
        printf("%d\n",sin.sin_addr.s_addr); //输出网络字节序
        printf("%s\n",inet_ntop(AF_INET,&sin.sin_addr.s_addr,buf,sizeof(buf)));
        return 0;
}

输出结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值