数据包头分析---网络字节序与主机字节序
udp头部数据结构
struct udphdr {
__be16 source; //16位源端口号
__be16 dest; //16位目的端口号
__be16 len; //指udp首部长度和udp数据的长度总和长度
__sum16 check; //udp校验和,校验的是udp首部和upd数据的总的校验和
};
,由此知,16bit*4=64bit=8字节,udp首部长度8字节。
如果tcp和udp同时提供某种知名服务,两个协议通常选择相同的端口号,这纯粹是为了使用的方便,而不是协议本身规定的
tcp头部数据结构
struct tcphdr {
__be16 source; //16位源端口号
__be16 dest; //16位目的端口号
//每个tcp段都包源和目的端口号,用于寻找发送端和接受端的应用进程。这两个端口号加上ip报头中的源ip和目的ip,来确定一个唯一的TCP连接。
__be32 seq; //此次发送的数据在整个报文段中的起始字节数。此序号用来标识从tcp发送端向tcp接受端发送的数据字节流,seq表示在这个报文段中的第一个数据字节。如果将字节流看做在两个应用程序间的单向流动,则tcp用序号对每个字节进行计数。32 bit的无符号数。为了安全起见,它的初始值是一个随机生成的数,它到达2的32次方-1后又从零开始。
__be32 ack_seq; //是下一个期望接收的字节,确认序号应当是上次已成功接收的序号+1,只有ack标志为1时确认序号字段才有效。一旦一个连接已经建立了,ack总是=1
#if defined(__LITTLE_ENDIAN_BITFIELD) //小端
__u16 res1:4, // 保留位
doff:4, //tcp头部长度,指明了在tcp头部中包含了多少个32位的字。由于options域的长度是可变的,所以整个tcp头部的长度也是变化的。4bit可表示最大值15,故15*32=480bit=60字节,所以tcp首部最长60字节。然后,没有任选字段,正常的长度是20字节
fin:1, //发端完成发送任务
syn:1, //同步序号用来发起一个连接
rst:1, //重建连接
psh:1, //接收方应该尽快将这个报文段交给应用层
ack:1, //一旦一个连接已经建立了,ack总是=1
urg:1, //紧急指针有效
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__be16 window; //窗口大小,单位字节数,指接收端正期望接受的字节,16bit,故窗口大小最大为16bit=1111 1111 1111 1111(二进制)=65535(十进制)字节
__sum16 check; //校验和校验的是整个tcp报文段,包括tcp首部和tcp数据,这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。
__be16 urg_ptr;
};
不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序
最常见的有两种
1. Little endian:将低序字节存储在起始地址
2. Big endian:将高序字节存储在起始地址
LE little-endian
最符合人的思维的字节序
地址低位存储值的低位
地址高位存储值的高位
怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说
低位值小,就应该放在内存地址小的地方,也即内存地址低位
反之,高位值就应该放在内存地址大的地方,也即内存地址高位
BE big-endian
最直观的字节序
地址低位存储值的高位
地址高位存储值的低位
为什么说直观,不要考虑对应关系
只需要把内存地址从左到右按照由低到高的顺序写出
把值按照通常的高位到低位的顺序写出
两者对照,一个字节一个字节的填充进去
例子:在内存中双字0x01020304(DWORD)的存储方式
内存地址
4000 4001 4002 4003
LE 04 03 02 01
BE 01 02 03 04
例子:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为
big-endian little-endian
0x0000 0x12 0xcd
0x0001 0x23 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12
x86系列CPU都是little-endian的字节序.
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。
为了进行转换 bsd socket提供了转换的函数 有下面四个
htons 把unsigned short类型从主机序转换到网络序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序
在使用little endian的系统中 这些函数会把字节序进行转换
在使用big endian类型的系统中 这些函数会定义成空宏
同样 在网络程序开发时 或是跨平台开发时 也应该注意保证只用一种字节序 不然两方的解释不一样就会产生bug.
注:
1、网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
2、不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。
处理器 操作系统 字节排序
Alpha 全部 Little endian
HP-PA NT Little endian
HP-PA UNIX Big endian
Intelx86 全部 Little endian <-----x86系统是小端字节序系统
Motorola680x() 全部 Big endian
MIPS NT Little endian
MIPS UNIX Big endian
PowerPC NT Little endian
PowerPC 非NT Big endian <-----PPC系统是大端字节序系统
RS/6000 UNIX Big endian
SPARC UNIX Big endian
IXP1200 ARM核心 全部 Little endian
数据包头分析---网络字节序与主机字节序相关推荐
- linux网络编程一:主机字节序与网络字节序的的判断
linux网络编程一:主机字节序与网络字节序的的判断(1)现代CPU的累加器一次能装载至少4字节(32位),即一个整数.那么这4字节在内存中排列的顺序将影响它被累加器装载成的整数值,这就是字节序问题 ...
- php 字节序,Linux_Linux中网络字节序和主机字节序,主机字节序就是我们平常说的 - phpStudy...
Linux中网络字节序和主机字节序 主机字节序就是我们平常说的大端和小端模式:不同的 CPU 有不同的字节序类型,这些字节序是指整数在内存中保存的顺序 这个叫做主机序.Big-Endian和Littl ...
- java 网络字节序转主机字节序_C语言高级编程——网络编程技术
了解什么是网络编程 熟悉七层网络模型 熟悉网络开发中使用到的函数 掌握TCP协议类程序开发 掌握UDP协议类程序开发 计算机本身是不会进行网络通信的,所以要想使通过软件进行网络通信,必须制定相应的规则 ...
- 网络字节序与主机字节序的相互转换
1.网络字节序与主机字节序 在Linux网络编程中,经常碰到网络字节序与主机字节序的相互转换.说到网络字节序与主机字节序需要清晰了解以下几个概念. 字节序,顾名思义,指字节在内存中存储的顺序.比如一个 ...
- 网络字节序和主机字节序
网络字节序说明 TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节.例如上一节的UDP段格式,地址0-1是16位的源端口号,如果这个端口号是1000(0x3e8),则地址0是0x03,地 ...
- java转网络字节序_【转】网络字节序与主机字节序
最近在项目开发过程中,需要在采用JAVA作为语言的服务器与采用C++作为语言的服务器间进行通信,这就涉及到这两种语言间数据类型的转换以及网络字节序与主机字节序的区别.该文主要说说网络字节序和主机字节序 ...
- C#之网络字节序与主机字节序互转
主机字节序转网络字节序 //加上两个字节长度,再发送byte[] bSend = new byte[buffer.Length + 2]; byte[] bLenth = BitConverter.G ...
- 网络字节序和主机字节序互转
1.网络字节序转为主机字节序 //网络字节序转为主机字节序 uint64_t utils::Ntohll(uint64_t val) {if (__BYTE_ORDER == __LITTLE_END ...
- 【转】大端模式与小端模式、网络字节顺序与主机字节顺序 (经典)
大端模式与小端模式 一.概念及详解 在各种体系的计算机中通常采用的字节存储机制主要有两种: big-endian和little-endian,即大端模式和小端模式. 先回顾两个关键词,MSB和LSB: ...
最新文章
- 优化webpack配置
- 2016/01/13开始学习git:分支管理:Bug分支
- 构造函数初始化结构体
- router3 BGP2 属性及选路
- hdu-5068 Harry And Math Teacher
- swift5.5异常的处理的三种的方式
- java 从excel中读取数据_java如何从excel中读出数据
- display: inline-block;水平居中
- MySQL无中心化集群_MySQL Plus 如何做到无中心化、数据强一致性、秒级切换?
- C语言_顺序结构的程序设计
- s905各种型号的区别_2020榨汁机推荐,榨汁机、原汁机和破壁机有什么区别?高性价比榨汁机、原汁机怎么选?...
- micropython和python区别-选择C/C++还是选择MicroPython来开发?(第0章-第三节)
- 如何在 Mac 上的“音乐”应用和 iTunes 中创建 Genius 播放列表?
- 面试小题,传入6返回9,传入9返回6
- python 读取文件名列表_python 读取指定文件夹下所有文件名
- xshell xftp免费版下载
- 暗黑破坏神(DIABLOII 1.11B)BOT 及源代码公开下载
- 小学六年级下册计算机计划,小学信息技术六年级下册教学计划
- 运维的升级打怪之路v2版
- matplotlib 画图总结