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( ...
随机推荐
- 从零开始学Spring Boot系列-前言
从零开始学Spring Boot系列-前言 在数字化和信息化的时代,Java作为一种成熟.稳定且广泛应用的编程语言,已经成为构建企业级应用的首选.而在Java生态系统中,Spring框架无疑是其中最为 ...
- VS2019 配置 Qt 库
如标题所说,在 VS 编译器中调用 Qt 库 首先安装一个适合 VS 的 Qt 版本 不知道怎么安装的,可以参考:Visual Studio+Qt配置开发环境 Qt 安装之后,需要在 VS 编译器中 ...
- 01、etcd基础介绍
互联网技术发展真的快,层出不穷的新技术.最近项目使用到了etcd,自己之前在部署k8s集群的时候玩过,但是并没有系统的学习.正好趁这个机会,系统性的学习下.文章中的内容有些是来自官方文档,有些是来自网 ...
- ECMA Script Module(ES module)知识点
1.每个 ES Module 都是运行在单独的私有作用,ESM 自动采用严格模式,忽略use strict <script type="module">console. ...
- GenAI助力DevOps,塑造软件工程的未来
自 2022 年以来,GenAI 无疑已成为一种普遍的技术趋势.在本文中,我们将探索 DevOps 中令人兴奋的 GenAI 领域,讨论其潜在优势.局限性.新兴趋势和最佳实践,深入了解 AI 支持的 ...
- JVM内存模式
Java内存模型即Java Memory Model,简称JMM. JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式.JVM 是整个计算机虚拟模型,所以 JMM 是隶属于 JV ...
- SPFA最短路
目录 从Bellman-Ford开始 核心思想 模拟算法执行过程 时间复杂度 模板 spfa spfa优化的思想 模板 从Bellman-Ford开始 对于所有边权都大于等于0的图,任意两个顶点之间的 ...
- Codeforces Round 729 (Div. 2)B. Plus and Multiply(构造、数学)
题面 链接 B. Plus and Multiply 题意 给定\(n,a,b\) 可以进行的操作 \(*a\) \(+b\) 最开始的数是1 问能否经过上面的两种操作将1变为n 题解 这题的关键是能 ...
- C++ STL之 map 学习笔记
•何为 map? map 是 STL 的一个关联容器,它提供一对一的数据处理,map 中存放的是一个 key-value键值对,其类型可以自己定义: 第一个可以称为关键字,每个关键字在 map 中只能 ...
- vuecli-vite-vue3-init 项目架子 快速开发 webpack打包
要vite的开发的快速 和 webpack打包 开发的时候 用vite,可以打包一个本地可以直接双击,不用起服务的代码 这个架子的缺点就是 vite和vuecli 两套双配置 正式公司项目 还是vue ...