专栏首页Tcp/ip 报文解析

Tcp/ip 报文解析

在编写网络程序时,常使用TCP协议。那么一个tcp包到底由哪些东西构成的呢?其实一个TCP包,首先需要通过IP协议承载,而IP报文,又需要通过以太网传送。下面我们来看看几种协议头的构成

一 .Ethernet头

以太帧分好几种类型,常见的以太帧为Ethernet II

下面就是一个典型的Ethernet II帧

Ethernet II类型以太网帧的最小长度为64字节(6+6+2+46+4),最大长度为1518字节(6+6+2+1500+4)

首先是目的MAC 6个字节,然后源MAC6个字节,接下来数据类型两个字节。

常见的类型如下

IPv4: 0x0800

ARP:0x0806

PPPoE:0x8864

802.1Q tag: 0x8100

IPV6: 0x86DD

MPLS Label:0x8847

然后是数据长度,46-1500字节。对于不定长的数据包,帧最后还有4个字节的FCS(Frame check sequence)

下面是一个以太帧头示例,该报文类型为IPv4(0x8000)

二 IP头部

对于一个IPv4类型的以太帧,数据的开始就是IP头部。一般IPv4的头部是20个字节。

版本号(Version):4bit。表明IP协议的版本号。一般为0100(IPv4),0110(IPv6)

IP包头长度(Header Length):4bit。用于描述IP包头长度,因为IP包头长度是可变的。

这里所指示的长度,是以4个字节为一个单位。例如,一个IP包头的长度最长为“1111”,即15*4=60个字节。IP包头最小长度为20字节。

服务类型(Type of Service):长度8比特。 IP包总长(Total Length):16bit。 以字节为单位计算的IP包的长度 (包括头部和数据),所以IP包最大长度65535字节。 标识符(Identifier):16bit。该字段和Flags和Fragment Offest字段联合使用,对较大的上层数据包进行分段(fragment)操作。路由器将一个包拆分后,所有拆分开的小包被标记相同的值,以便目的端设备能够区分哪个包属于被拆分开的包的一部分。

标记(Flags):3bit。第一位是保留位不使用。第二位是DF(Don't Fragment)位,DF位设为1时表明路由器不能对该数据包分包。如果一个数据包无法在不分段的情况下发送,则路由器会丢弃该数据包并返回一个错误信息。第三位是MF(More Fragments)位,当路由器对一个上层数据包分段,则路由器会在除了最后一个分段的IP包的包头中将MF位设为1。

片偏移(Fragment Offset):13bit。表示该IP包在该组分片包中位置,接收端靠此来组装还原IP包。

生存时间(TTL):8bit。当IP包在网络上传送时,每经过一个路由器,TTL就自动减一。值为0时,则丢弃报文。防止报文进入环路

协议(Protocol):8bit。标识IP头后面的报文协议类型 以下是比较常用的协议号:

1    ICMP

2    IGMP

6    TCP

17    UDP

88    IGRP

89    OSPF

头校验和(Header Checksum):16bit。用来做IP头部的正确性检测,但不包含数据部分。由于路由器会改变TTL,所以路由器会为每个通过的数据包重新计算这个值。

源和目的地址(Source and Destination Addresses):这两个地段都是32比特。标识了这个IP包的起源和目标地址。要注意除非使用NAT,否则整个传输的过程中,这两个地址不会改变。

下图就是一个IP头的内容

三 TCP 头部

TCP封装在IP报文中的时候,如下图所示,TCP头紧接着IP头(IPV6有扩展头的时候,则TCP头在扩展头后面),不携带选项(option)的TCP头长为20bytes,携带选项的TCP头最长可到60bytes。

源端口(Source Port):16bit, 表示报文发送方的端口号

目的端口(Destination port): 16bit,表示报文接收方的端口号

序列号(SN):32bit,标识了TCP报文中第一个byte在对应方向的传输中对应的字节序号。当SYN出现,序列码实际上是初始序列码(ISN),而第一个数据字节是ISN+1,单位是byte。比如发送端发送的一个TCP包净荷(不包含TCP头)为12byte,SN为5,则发送端接着发送的下一个数据包的时候,SN应该设置为5+12=17。通过系列号,TCP接收端可以识别出重复接收到的TCP包,从而丢弃重复包,同时对于乱序数据包也可以依靠系列号进行重排序,进而对高层提供有序的数据流。另外SYN标志和FIN标志在逻辑上也占用一个byte,当SYN标志位有效的时候,该字段也称为ISN(initial sequence number),详细请参考后续的TCP连接管理。

应答号(ACK):32bit,标识了报文发送端期望接收的字节序列。如果设置了ACK控制位,这个值表示一个准备接收的包的序列码,注意是准备接收的包,比如当前接收端接收到一个净荷为12byte的数据包,SN为5,则发送端可能会回复一个确认收到的数据包,如果这个数据包之前的数据也都已经收到了,这个数据包中的ACK Number则设置为12+5=17,表示17byte之前的数据都已经收到了。在举一个例子,如果在这个数据包之前有个SN为3,净荷为2byte的数据包丢失,则在接受端接收到这个SN为5的乱序数据包的时候,协议要求接收端必须要回复一个ACK确认包,这个确认包中的Ack Number只能设置为3。

头长(Header Length):4bit,指示TCP头的长度,即数据从何处开始。最大为15,单位是32比特,即4个字节,与IP头中的长度定义相同。

保留(Reserved):4bit,这些位必须是0。为了将来定义新的用途所保留,其中RFC3540将Reserved字段中的最后一位定义为Nonce标志。

标志(Code Bits):8bit

CWR(Congestion Window Reduce):拥塞窗口减少标志被发送主机设置,用来表明它接收到了设置ECE标志的TCP包,发送端将通过降低发送窗口的大小来降低发送速率

ECE(ECN Echo):ECN响应标志被用来在TCP3次握手时表明一个TCP端是否具备ECN功能,并且表明接收到的TCP包的IP头部的ECN被设置为11。更多信息请参考RFC793。

URG(Urgent):表示紧急(The urgent pointer) 指针是否有效。

ACK(Acknowledgment):1表示这是一个确认的TCP包, 0则不是确认包。

PSH(Push):该标志置位时,一般是表示发送端缓存中已经没有待发送的数据,接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。

RST(Reset):用于复位相应的TCP连接。通常在发生异常或者错误的时候会触发复位TCP连接。

SYN(Synchronize):表示同步序列编号(Synchronize Sequence Numbers)是否有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接发起端(一般是客户端)的初始序列编号。在这里,可以把TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。

FIN(Finish):带有该标志置位的数据包用来结束一个TCP会话,但对应端口仍处于开放状态,准备接收后续数据。当FIN标志有效的时候我们称呼这个包为FIN包。

窗口大小(Window Size):16bit,表示从Ack Number开始还能接收多少字节的数据量,即当前接收端的接收窗口还有多少剩余空间。用于TCP的流量控制。

校验和(Checksum):16bit。发送端基于数据内容计算一个数值,接收端要与发送端数值结果完全一样,才能证明数据的有效性。接收端checksum校验失败的时候会直接丢掉这个数据包。CheckSum是根据伪头+TCP头+TCP数据三部分进行计算的。

紧急指针(Urgent  Pointer):16位,在URG标志设置了时才有效。与序号字段的值相加后表示最后一个紧急数据的下一字节的序号,可以说这个字段是紧急指针相对当前序号的偏移。

选项(Option):长度不定,但长度必须以是32bits的整数倍。常见的选项包括MSS、SACK、Timestamp等等,后续的内容会分别介绍相关选项。

一个完整的TCP头展示

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • sql语句练习50题(Mysql版)

  • 拼多多面试题

    2、看你在项目中用了redis,我们先聊聊redis吧,常用的数据结构有哪几种,在你的项目中用过哪几种,以及在业务中使用的场景,redis的hash怎么实现的,...

  • shell 编程记录

    1 文件比较运算符 -e filename 如果 filename存在,则为真 [ -e /var/log/syslog ] -d filename 如果...

  • 计算机揭秘之:网络分类和性能分析

    程序员天天都在写代码,关注的都是更高层次的封装,今天我们换个思路,让程序那些事来带你看一看隐藏在表象之下的网络和他们的性能分析。

    程序那些事
  • 网络编程 | TCP/IP基础知识

    在2017年10月深圳 Cocos 沙龙上,有幸结识了社区中大名顶顶的Colin,Shawn在论坛上第一次看到Colin的团队用CocosCreator制作的《...

    张晓衡
  • 网络编程懒人入门(一):快速理解网络通信协议(上篇)

    论坛和群里常会有技术同行打算自已开发IM或者消息推送系统,很多时候连基本的网络编程理论(如网络协议等)都不了解,就贸然定方案、写代码,显得非常盲目且充满技术风险...

    JackJiang
  • 网络号和主机号的计算

    因为想要学习网络号和主机号的计算需要先知道其IP地址和子网掩码,所以这篇博客的学习是以上一篇IP地址分类及私网IP为基础的。 具体为: 网络号=IP地址&子网掩...

    用户1215536
  • TCP-IP详解卷1:协议 学习笔记(3) IP:网际协议

    服务类型TOS字段包括一个3bit的优先权子字段(现在已经被忽略),4bit的TOS子字段和1bit未用位但必须置0。4bit的TOS分别代表:最小时延、最大吞...

  • 计算机网络面试题 系列一(排名400多还不不错)

    http://blog.csdn.net/tianshuai1111/article/details/8121881

    bear_fish
  • 5G时代已经到来,TCP/IP老矣,尚能饭否?

    是的,自从我整理完《IM开发者的零基础通信技术入门》系列文章之后,对于网络编程的理解,开始有点飘了。

    JackJiang

扫码关注云+社区

领取腾讯云代金券