TCP/IP 组包过程
TCP/IP四层模型如下:
应用层数据需要经过TCP/IP每一层处理之后才能通过网络传输到目的端,每一层上都使用该层的协议数据单元PDU(ProtocolDataUnit)彼此交换信息。
上层数据在传输层添加TCP报头后得到的PDU被称为Segment(数据段);数据段被传递给网络层,网络层添加IP报头得到的PDU被称为Packet(数据包);数据包被传递到数据链路层,封装数据链路层报头得到的PDU被称为Frame(数据帧);最后,帧被转换为比特,通过网络介质传输。这种协议栈逐层向下传递数据,并添加报头和报尾的过程称为封装。
传输层头部
TCP头部
1)源端口和目的端口:用于寻找发端和收端的应用程序。这两个值加上IP首部的源端IP和目的端IP唯一确定一个TCP连接;
2)序号(Seq):标识从TCP发端向TCP收端发送的数据字节流,它标识在这个报文段中的第一个数据字节的序号。如果将字节流看作在两个应用程序间的单向流动,则TCP用序号对每个字节进行计数。序号是32bit的无符号数,序号到达2的32次方减一后又从0开始。SYN标志消耗一个序号;
3)确认序号(ACK):如果上次成功收到数据字节序号加一。只有ACK标志为1时确认序号才有效,ACK = Seq + 1;
4)数据偏移:标识该TCP头部有多少个32bit(4字节),4比特最大表示15,TCP头部最长为60字节;
5)窗口:TCP流量控制的手段,告诉对方,我的TCP接收端缓冲区还能容纳多少个字节,这样对方能控制发送数据的速度;
6)校验和:由发送端填充,接收端对TCP报文执行CRC算法,以检验TCP报文段是否损毁。不仅校验头部,还包括数据部分;
7)紧急指针:也称为紧急偏移。紧急指针是一个正的偏移量,和序号字段的值相加表示最后一个紧急指针的下一字节的序号。是相对于当前序号的偏移。紧急指针
是发送端向接收端发送紧急数据的方法;
8)六个标志位:
- a)URG:表示紧急指针是否有效;
- b)ACK:表示确认号是否有效,携带ACK标志的数据报文段为确认报文段;
- c)PSH:提示接收端的应用程序应该立即从TCP接受缓冲区中读走数据,为接收后面数据腾出空间;
- d)RST:表示要求对方重新建立连接,携带RST标志位的TCP报文段称为复位报文段;
- e)SYN: 表示请求建立一个连接,携带SYN标志的TCP报文段称为同步报文段;
- f)FIN:通知对方本端要关闭了,带FIN标志的TCP报文段称为结束报文段;
9)TCP头部选项:头部选项是一个可变长的信息,这部分最多包含40个字节(前面20字节是固定的)
头部选项的实际运用(一般包含在三次握手中)
- a)最大报文传输段(Maxinum Segment Size——MSS)
- b)窗口扩大选项(window scaling)
- c)选择确认选项(Selective Acknowledgements——SACK)
- d)NOP
TCP在三次握手建立连接过程中,会在SYN报文中使用MSS(Maximum Segment Size)选项功能,协商交互双方能够接收的最大段长MSS值。
UDP头部
UDP首部有8个字节,由4个字段构成,每个字段都是两个字节,
- 1.源端口: 源端口号,需要对方回信时选用,不需要时全部置0.
- 2.目的端口:目的端口号,在终点交付报文的时候需要用到。
- 3.长度:UDP的数据报的长度(包括首部和数据)其最小值为8(只有首部)
- 4.校验和:检测UDP数据报在传输中是否有错,有错则丢弃。该字段是可选的,当源主机不想计算校验和,则直接令该字段全为0.
如果接收方UDP发现收到的报文中的目的端口号不正确(不存在对应端口号的应用进程0,),就丢弃该报文,并由ICMP发送“端口不可达”差错报文给对方。
在计算校验和的时候,需要在UDP数据报之前增加12字节的伪首部,伪首部并不是UDP真正的首部。只是在计算校验和,临时添加在UDP数据报的前面,得到一个临时的UDP数据报。校验和就是按照这个临时的UDP数据报计算的。伪首部既不向下传送也不向上递交,而仅仅是为了计算校验和。这样的校验和,既检查了UDP数据报,又对IP数据报的源IP地址和目的IP地址进行了检验。
网络层
IPv4头部
(1)版本号:长度4bit,标识目前采用的IP协议的版本号,一般的值0100(IPv4),0110(IPv6)
(2)首部长度:长度4bit,这个字段的作用是为了描述IP头部的长度,IP头部长度是可变的(最常用的是红框中的部分,一共占20字节
),单位是word
(3)服务类型(Type Of Service,TOS):3位优先权字段(现已被忽略)+4位TOS字段+1位保留字段(须为0)。4位TOS字段分别表示最小延时、最大吞吐量、最高可靠性、最小费用,其中最多有一个置为1。应用程序根据实际需要来设置 TOS值,如ssh和telnet这样的登录程序需要的是最小延时的服务,文件传输ftp需要的是最大吞吐量的服务
(4)总长度:指整个IP数据报的长度(即:IP数据报中首部和数据的总和的长度),占16位,单位为字节,故IP数据报的最大长度为65535字节(2的16次方)。由于MTU的限制,长度超过MTU的数据报都将被分片传输,所以实际传输的IP分片数据报的长度远远没有达到最大值。
下来的3个字段则描述如何实现分片:
(5)标识:唯一地标识主机发送的每一个数据报,其初始值是随机的,每发送一个数据报其值就加1。同一个数据报的所有分片都具有相同的标识值。
(6)标志:位1保留,位2表禁止分片(DF),若设置了此位,IP模块将不对数据报进行分片,在此情况下若IP数据报超过MTU,IP模块将丢弃数据报并返回一个ICMP差错报文;位3标识分片(MF),表示后面还有若干个数据报,除了数据报的最后一个分片,其他分片都要把它设置为1。
(7)片偏移:分片相对原始IP数据报数据部分的偏移。实际的偏移值为该值左移3位后得到的,所以除了最后一个IP数据报分片外,每个IP分片的数据部分的长度都必须是8的整数倍。
(8)生成时间TTL:数据报到达目的地之前允许经过的路由器跳数。TTL值被发送端设置,常设置为64。数据报在转发过程中每经过一个路由该值就被路由器减1.当TTL值为0时,路由器就将该数据包丢弃,并向源端发送一个ICMP差错报文。TTL可以防止数据报陷入路由循环。
(9)协议:区分IP协议上的上层协议。在Linux系统的/etc/protocols文件中定义了所有上层协议对应的协议字段,ICMP为1,TCP为6,UDP为17。
(10)头部校验和: 由发送端填充接收端对其使用CRC算法校验,检查IP数据报头部在传输过程中是否损坏
(11)源和目标地址是32bit,标识了这个IP包的起源和目的地址(源IP地址指的就是发送数据包的那个电脑的IP地址,目的IP地址就是想要发送到的那个电脑的IP地址),要注意除非使用NAT,否则整个传输的过程中,这两个地址不会改变。
(12)目的地址:占32位
(13)选项:可变长的可选信息,最多包含40字节。选项字段很少被使用。可用的IP可选项有:
a. 记录路由: 记录数据包途径的所有路由的IP,这样可以追踪数据包的传递路径
b. 时间戳: 记录每个路由器数据报被转发的时间或者时间与IP地址对,这样就可以测量途径路由之间数据报的传输的时间
c. 松散路由选择: 指定路由器的IP地址列表数据发送过程中必须经过所有的路由器
d. 严格路由选择: 数据包只能经过被指定的IP地址列表的路由器
e. 上层协议(如TCP/UDP)的头部信息
在IP协议中,IP协议是面向非连接的,所谓的非连接就是在数据的传递过程中,不需要检测网络是否连通,所以是不可靠的数据报协议。IP协议主要用于在主机之间的寻址和选择数据包路由。
网络接口层
数据链路层
以太网头部
Ethernet 协议规定 DatalinkHeader 是 14 bytes,分别是6字节目的MAC地址、6字节源MAC地址、2字节数据包类型;
4字节FCS(frame check sequence)是CRC值;