IPv4地址的结构体与网络字节序
IPv4地址的结构体
/* Fixed-size types, underlying types depend on word size and compiler. */
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;
#if __WORDSIZE == 64
typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;
#else
__extension__ typedef signed long long int __int64_t;
__extension__ typedef unsigned long long int __uint64_t;
#endif
/* Internet address. */
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};
/* POSIX.1g specifies this type name for the `sa_family' member. */
typedef unsigned short int sa_family_t;
/* This macro is used to declare the initial common members
of the data types used for socket addresses, `struct sockaddr',
`struct sockaddr_in', `struct sockaddr_un', etc. */
#define __SOCKADDR_COMMON(sa_prefix) \
sa_family_t sa_prefix##family
/* Structure describing a generic socket address. */
struct sockaddr
{
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
char sa_data[14]; /* Address data. */
};
/* Structure describing an Internet socket address. */
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
in_port_t sin_port; /* Port number. */
struct in_addr sin_addr; /* Internet address. */
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr)
- __SOCKADDR_COMMON_SIZE
- sizeof (in_port_t)
- sizeof (struct in_addr)];
};
sin_family: 每种协议族使用的地址族均不同,IPv4使用4字节地址族,IPv6使用16字节地族。
Name Purpose Man page
AF_UNIX Local communication unix(7)
AF_LOCAL Synonym for AF_UNIX
AF_INET IPv4 Internet protocols ip(7)
AF_IPX IPX - Novell protocols
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_PACKET Low-level packet interface packet(7)
sin_port: 用于以网络字节序保存16位端口号。
sin_addr: 用于以网络字节序保存32IP地址。同时观察结构体,in_addr。该结构体声明为uint32_t,因此只需要当作32位整数即可。
/* Internet address. */
typedef unsigned int __uint32_t;
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};
sin_zero: 无特殊意义。只是为结构体sockaddr_in的大小与sockaddr结构体保持一致而插入的成员,必须填充为零。bind函数在第二个参数就得到sockaddr的结构体变量地址值。此结构体成员sa_data保存的地址信息中需包含IP地址和端口号剩余部分填充零。
/* POSIX.1g specifies this type name for the `sa_family' member. */
typedef unsigned short int sa_family_t;
/* This macro is used to declare the initial common members
of the data types used for socket addresses, `struct sockaddr',
`struct sockaddr_in', `struct sockaddr_un', etc. */
#define __SOCKADDR_COMMON(sa_prefix) \
sa_family_t sa_prefix##family
/* Structure describing a generic socket address. */
struct sockaddr
{
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
char sa_data[14]; /* Address data. */
};
# define __CONST_SOCKADDR_ARG const struct sockaddr *
/* Give the socket FD the local address ADDR (which is LEN bytes long). */
extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
__THROW;
if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof servaddr) < 0) {
perror("bind");
}
字节序(Order)网络字节序
计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。举例来说,数值0x3322使用两个字节储存:高位字节是0x33,低位字节是0x22。网路字节序统一为大端字节序。
- 大端字节序:高位字节在前,低位字节在后,这是人类读写数值的方法。
- 小端字节序:低位字节在前,高位字节在后,即以0x2233形式储存。
字节序转换
/* Functions to convert between host and network byte order.
Please note that these functions normally take `unsigned long int' or
`unsigned short int' values as arguments and also return them. But
this was a short-sighted decision since on different systems the types
may have different representations but the values are always the same. */
extern uint32_t ntohl (uint32_t __netlong) __THROW __attribute__ ((__const__));
extern uint16_t ntohs (uint16_t __netshort)
__THROW __attribute__ ((__const__));
extern uint32_t htonl (uint32_t __hostlong)
__THROW __attribute__ ((__const__));
extern uint16_t htons (uint16_t __hostshort)
__THROW __attribute__ ((__const__));
- htonl中的h表示主机(host)字节序。
- htonl中的n表示网络(network)字节序。
- htonl中的s表示short,l表示long。
通常s代表2字节short,因此用于端口号转换,l代表4字节long,因此用于IP地址转换。
字符串信息转化为网络字节序的整数型
//成功时返回32位大端序整数型值,失败时返回INADDR_NONE,并且可以检测无效IP地址。
in_addr_t inet_addr(const char *__cp)
//成功时返回1(true),失败时返回0(false)
int inet_aton(const char *__cp, struct in_addr *__inp)
- __cp:含有需转换的IP地址信息的字符串地址值。
- __inp:将保存结果的in_addr结构体变量的地址值。
//成功时返回转换的字符串地址值,失败时返回-1
char *inet_ntoa(struct in_addr __in)
适用于IPv4地址和IPv6地址地址转换函数
/* Convert from presentation format of an Internet number in buffer
starting at CP to the binary network format and store result for
interface type AF in buffer starting at BUF. */
extern int inet_pton (int __af, const char *__restrict __cp,void *__restrict __buf) __THROW;
/* Convert a Internet address in binary network format for interface
type AF in buffer starting at CP to presentation form and place
result in buffer of length LEN astarting at BUF. */
extern const char *inet_ntop (int __af, const void *__restrict __cp,char *__restrict __buf, socklen_t __len) __THROW;
inet_pton函数将用字符串表示的IP地址src(用点分十进制字符串表示的IPv4地址或用十六进制字符串表示的IPv6地址)转换成用网络字节序整数表示的IP地址,并把转换结果存储于dst指向的内存中。其中,af 参数指定地址族,可以是AF_ INET 或者AF_ INET6。inet_ pton 成功时返回1,失败则返回0并设置errno日。inet ntop 函数进行相反的转换,前三个参数的含义与inet pton的参数相同,最后一个参数cnt指定目标存储单元的大小。下面的两个宏能帮助我们指定这个大小(分别用于IPv4和IPv6):
#include <netinet/in.h>
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
inet_ ntop 成功时返回目标存储单元的地址,失败则返回NULL并设置ermo。
INADDR_ANY
/* 自动获取服务端的计算机IP地址 */
#define INADDR_ANY ((in_addr_t) 0x00000000)
IPv4地址的结构体与网络字节序的更多相关文章
- Linux 网络编程详解一(IP套接字结构体、网络字节序,地址转换函数)
IPv4套接字地址结构 struct sockaddr_in { uint8_t sinlen;(4个字节) sa_family_t sin_family;(4个字节) in_port_t sin_p ...
- vxworks下网络编程一:网络字节序问题
inet_addr("192.168.1.1");//返回网络字节序整型ip地址inet_ntoa(saddr);//将包含网络字节序整型ip地址的in_addr对象转换成本地ch ...
- 【网络编程一】主机字节序与网络字节序以及ip地址转换函数
在计算机设计之初,对内存中数据的处理也有不同的方式,(低位数据存储在低位地址处或者高位数据存储在低位地址处),然而,在通信的过程中(ISO/OSI模型和TCP/IP四层模型中),数据被一步步封装(然后 ...
- Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。
倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offse ...
- linux的大小端、网络字节序问题 .
1.80X86使用小端法,网络字节序使用大端法. 2.二进制的网络编程中,传送数据,最好以unsigned char, unsigned short, unsigned int来处理, unsigne ...
- TCP和UDP的区别与联系以及网络字节序和主机字节序的转换函数实践
TCP和UDP的区别 TCP是一个面向连接的.可靠的.基于字节流的传输层协议. 而UDP是一个面向无连接的传输层协议. 具体来分析,和 UDP 相比,TCP 有三大核心特性: 面向连接:所谓的连接,指 ...
- 大端字节序&小端字节序(网络字节序&主机字节序)
大端字节序:整数的高位字节存储在内存的低地址处,低字节存储在内存的高地址处. 小端字节序:整数的高位字节存储在内存的高地址处,低字节存储在内存的低地址处. 一般pc大多采用小端字节序,也称为主机字节序 ...
- Python网络编程——主机字节序和网络字节序之间的相互转换
If you ever need to write a low-level network application, it may be necessary to handle the low-lev ...
- c# 主机和网络字节序的转换 关于网络字节序和主机字节序的转换
最近使用C#进行网络开发,需要处理ISO8583报文,由于其中有些域是数值型的,于是在传输的时候涉及到了字节序的转换. 字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有两种字节顺序, ...
- 清晰讲解LSB、MSB和大小端模式及网络字节序
时隔一个月又回到了博客园写文章,很开心O(∩_∩)O~~ 今天在做需求的涉及到一个固件版本的概念,其中固件组的人谈到了版本号从MSB到LSB排列,检索查阅后将所得整理如下. MSB.LSB? MSB( ...
随机推荐
- Java集合框架学习(三) TreeSet详解
TreeSet介绍 1.TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态. 2.向TreeSet中加入的应该是同一个类的对象. 3.TreeSet判断两个 ...
- win32- 使用WM_NCPAINT在非客户区域绘制边框
#pragma comment(lib, "UxTheme") #include <windows.h> #include <uxtheme.h> LRES ...
- Nacos2作为Dubbo3的配置中心踩坑总结
本文阐述问题所使用的组件版本分别是,Dubbo:3.2.4,Nacos服务端:2.2.3,Nacos客户端:2.2.4. 在Dubbo3的官方文档中,关于如何使用Nacos作为配置中心的详细介绍参考: ...
- 异步aioredis连接时报错TypeError: duplicate base class TimeoutError问题
版本 python3.11版本,aioredis 2.0.1版本,redis 7.x版本 redis.conf配置文件 daemonize yes bind 0.0.0.0 port 6379 pro ...
- python中partial用法
应用 典型的,函数在执行时,要带上所有必要的参数进行调用.然后,有时参数可以在函数被调用之前提前获知.这种情况下,一个函数有一个或多个参数预先就能用上,以便函数能用更少的参数进行调用. 示例pyqt5 ...
- Ubuntu虚拟机开机显示initramfs
因为我的虚拟机路径放在了移动硬盘当中,所以连接有点失常就断开了,紧接着虚拟机也异常关闭了. 重启后进入了initramfs界面 查看出错的分区,如下图所示,是/dev/sda5分区有损坏 解决方法: ...
- Java 创建类,对象+调用方法
1 //测试类 2 public class PersonTest 3 { 4 public static void main(String[] args) 5 { 6 //创建Person类的对象 ...
- Centos8 ssh配置三台虚拟机免密登录 root 及 非root 稍有差异;SSH的免密登录详细步骤
为了保证一台Linux主机的安全,所以我们每个主机登录的时候一般我们都设置账号密码登录.但是很多时候为了操作方便,我们都通过设置SSH免密码登录. 一.配置SSH 基本语法:假设要用用户名root登录 ...
- redis分片sharding实现原理
为什么集群? 通常,为了提高网站响应速度,总是把热点数据保存在内存中而不是直接从后端数据库中读取.Redis是一个很好的Cache工具.大型网站应用,热点数据量往往巨大,几十G上百G是很正常的事儿,在 ...
- Codeforces(1500板刷)
目录 写在前面 1. A. Did We Get Everything Covered?(构造.思维) 题目链接 题意 题解 代码 总结 2 F. Greetings(离散化+树状数组) 题目链接 题 ...