字节序
字节序分为大端字节序和小端字节序
大端字节序: 是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。
小端字节序: 是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。
x86框架采用小端字节序,ARM架构启动时可以 设置大小端字节序。
网络字节序采用大端字节序。
字节序的转换:
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
h表示host,n表示network,l表示32位长整数,s表示16位短整数。
地址族
一般而言,在使用套接字通信之前,我们首先要为套接字选定一个地址族(IPv4
或 IPv6
)。
在Linux系统中,sys/socket.h头文件定义了繁多的地址族类型,它们都是“AF_”或"IPv6".
地址族 | 说明 |
---|---|
AF_INET | 使用TCP或UDP来传输,用IPv4的地址 |
AF_INET6 | 使用TCP或UDP来传输,用IPv6的地址。 |
AF_UNIX | 本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用。 |
地址结构
很多网络编程函数诞生早于IPv4协议,那时候都使用的是sockaddr
结构体,为了向前兼容,现在sockaddr
退化成了(void *
)的作用,传递一个地址给函数,至于这个函数是sockaddr_in
还是sockaddr_in6
,由地址族确定,然后函数内部再强制类型转化为所需的地址类型。

#include <sys/socket.h>
struct sockaddr {
sa_family_t sa_family; /* 地址族 */
char sa_data[14]; /*地址值,实际可能更长*/
};
/*IPV4*/
struct sockaddr_in {
__kernel_sa_family_t sin_family; /* AF_INET4 */
__be16 sin_port; /*端头号*/
struct in_addr sin_addr; /* IPv4 地址 */
/* 8字节填充 */
unsigned char __pad[__SOCK_SIZE__ ‐ sizeof(short int) ‐
sizeof(unsigned short int) ‐ sizeof(struct in_addr)];
};
struct in_addr {
__be32 s_addr;
};
/*IPV6*/
struct sockaddr_in6 {
unsigned short int sin6_family; /*AF_INET6*/
__be16 sin6_port; /* 端口 # */
__be32 sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 地址 128bit*/
__u32 sin6_scope_id; /* scope id (new in RFC2553) */
};
struct in6_addr {
union {
__u8 u6_addr8[16];
__be16 u6_addr16[8];
__be32 u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};
#define UNIX_PATH_MAX 108
/*本地socket通信*/
struct sockaddr_un {
__kernel_sa_family_t sun_family; /* AF_UNIX */
char sun_path[UNIX_PATH_MAX]; /* pathname */
};
ip转换
ipv4
以及的ipv6
点分十进制表达法与二进制整数之间的互转。
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
inet_pton
把字符串src
转换成ip
地址保存在 dst
中。该函数调用成功返回大于0
的整数。
inet_ntop()
把网络字节序的ip地址src
转换成字符串保存在 dst
中作为返回值返回,参数 size
为dst
所包含的字节数。
af
用来指定要转换的ip属于什么协议族
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
int main(int argc, char** argv)
{
struct sockaddr_in sin;
char buf[16];
memset(&sin, 0, sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_port=htons(3001);
inet_pton(AF_INET, "192.168.1.111", &sin.sin_addr.s_addr);
printf("%s\n", inet_ntop(AF_INET, &sin.sin_addr, buf, sizeof(buf)));
return 0;
}
网友评论