【无标题】


前言

本次博客不是介绍socket,而是我讲一下socket当中地址、端口的转换函数。今天本来在开心的搓muduo网络库,看到它需要实现InetAddrss类,类的作用是将sockaddr的初始化封装起来,看到这里,我说这不简单吗,随便写一下就行,但是当我真正开始写的时候才发现,我好多api都忘记了,比如如何将sockaddr_in.sin_addr.s_addr转换为字符串,或者如何将字符串转化为s_addr,所以这篇博客我准备复习一下地址端口的转化。

一、sockaddr_in介绍

所在头文件

include <netinet/in.h>

结构体定义


typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
struct in_addr{
    in_addr_t s_addr;
 };
struct sockaddr_in{
 	in_port_t sin_port;			
    struct in_addr sin_addr;		
    unsigned char sin_zero[...];//这部分是用来适配sockaddr大小的,暂时不管
};

以上就是sockaddr_in的定义,首先,port就是一个2字节无符号整数,而端口号正好也这么大;然后是s_addr,看起来套了几层很麻烦,但是其实用起来很简单,就是拿一个32位大小的空间记录ipv4地址(ipv4大小就是32位),那为什么要搞这么奇怪?这其实是历史原因,大家知道怎么用就行了(我忘了是具体是什么原因了~~~)。sin_zero是用来使其大小和sockaddr变得相同,同时便于扩展。

二、网络字节序

通常计算机分为大端和小端,大端是指数据高位字节存在低地址,小端相反,高位字节存在高地址,举个例子,有个32位整数的16进制表示为:0x01020304,那么在大端系统中,地址从低到高存储的内容依次为:01 02 03 04,而在小端:04 03 02 01。但是在网络传输中,信息是以字节传输,两台大小端不同的机器也会使用字节传输,那么传输的时候就要统一大小端,而sockaddr_in是会存在于发送的信息中的,所以需要统一大小端,所以接下来介绍如何统一大小端。

三、统一大小端

//将32位长整型转化位网络字节序形式
uint32_t htonl(uint32_t hostlong);
//将16位短整型转化位网络字节序形式
uint16_t htons(uint16_t hostshort);
//将32位网络字节序转化位本地大小端形式
uint32_t ntohl(uint32_t netlong);
//将16位网络字节序转化位本地大小端形式
uint16_t ntohs(uint16_t netshort);
struct sockaddr_in addr;
memset(&addr,0,sizeof(addr));
addr_.sin_family = AF_INET;
addr_.sin_port = ::htons(port);//port:uint16_t
addr_.sin_addr.s_addr = htonl(ip); //ip:uint32_t

四、字符串与端口、地址之间的转化

//将点分十进制IP转化为网络字节序存放在addr中,并返回该网络字节序对应的整数。
int inet_aton(const char *cp, struct in_addr *inp);
//将点分十进制IP转化为网络字节序
in_addr_t inet_addr(const char *cp);
//将点分十进制IP转化为主机字节序
in_addr_t inet_network(const char *cp);
//网络字节序的地址转化为字符串,但是不推荐,因为不可重入
char *inet_ntoa(struct in_addr in);

/*
用得很少
struct in_addr inet_makeaddr(in_addr_t net, in_addr_t host);
in_addr_t inet_lnaof(struct in_addr in);
in_addr_t inet_netof(struct in_addr in);
*/
/*
af:地址族。 
src:点分十进制字符串格式的IP地址(如 "192.168.1.1" 或 "2001:db8::1")。
dst:用于存储网络字节序的二进制格式的 IP 地址,通常是 struct in_addr 或 struct in6_addr。

返回值
1:成功转换。
0:输入字符串格式非法。
-1:出错,并将错误代码存储在 errno 中。

作用
将字符串格式的 IP 地址转换为网络字节序的二进制格式。
支持 IPv4 和 IPv6 地址。
*/
int inet_pton(int af, const char *src, void *dst);
/*
参数
af:地址族
src:网络字节序的二进制格式 IP 地址(struct in_addr 或 struct in6_addr)。
dst:输出字符串缓冲区,存储转换后的字符串格式 IP 地址。size:dst 缓冲区的大小。

返回值
成功时返回指向输出字符串的指针。出错时返回 NULL,并设置 errno。

作用
将网络字节序的二进制格式 IP 地址转换为字符串格式。
*/
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值