TCP报文格式说明

首先理解一个概念(TCP/UDP)都是为了建立连接,只有建立连接,之后才有http或者rpc什么什么的事

TCP首部(报文)段概念图

在这里插入图片描述

报文概念解释(1b=8位):

端口号:

用来标识同一台计算机的不同应用进程

源端口(2个字节):

源端口和IP地址的作用是标识报文的返回地址

目的端口(2个字节)

端口指明接收方计算机上的应用程序接口

TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接

序号(4个字节):

TCP 是面向字节流的,在一个 TCP 连接中传输的字节流中的每个字节都按照顺序编号。

例如 100 kb 的 HTML 文档数据,一共 102400 (100 * 1024) 个字节,那么每一个字节就都有了编号,整个文档的编号的范围是 0 ~ 102399。

序号字段值指的是本报文段所发送的数据的第一个字节的序号。

那么 100 的 HTML 文档分割成四个等分之后:

  1. 第一个 TCP 报文段包含的是第一个 25kb 的数据,0 ~ 25599 字节, 该报文的序号的值就是:0

  2. 第二个 TCP 报文段包含的是第二个 25kb 的数据,25600 ~ 51199 字节,该报文的序号的值就是:25600

根据 8 位 = 1 字节,那么 4 个字节可以表示的数值范围:[0, 2^32],一共 2^32 (4294967296) 个序号。而序号增加到最大值的时候,下一个序号又回到了 0。也就是说 TCP 协议可对 4GB (410241024*1024)的数据进行编号,在一般情况下可保证当序号重复使用时,旧序号的数据早已经通过网络到达终点或者丢失了。

确认号ACK(4个字节):

确认号,即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。

数据偏移(0.5个字节):

数据偏移也叫作首部长度或者**头部长度。**这个字段实际上是指出了 TCP 报文段的首部长度 ,它指出了 TCP报文段的数据起始处 距离 TCP报文的起始处有多远。(注意 数据起始处 和 报文起始处 的意思)。

一个数据偏移量 = 4 byte,由于 4 位二进制数能表示的最大十进制数字是 15,因此数据偏移的最大值是 60 byte,这也侧面限制了 TCP 首部的最大长度。也就是TCP首部最大为60byte

保留(0.75个字节):

保留为今后使用,但目前应置为 0。(预留字段)

标志位(URG、ACK、PSH、RST、SYN、FIN。0.75个字节):

一共六个,从左至右分别是URG、ACK、PSH、RST、SYN、FIN

  1. URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。

  2. ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。

  3. PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。

  4. RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。

  5. SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。

  6. FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。

窗口(2个字节):

TCP流量控制通过连接的每一端声明窗口大小进行控制(接收缓冲区大小)。

该字段明确指出了现在允许对方发送的数据量,它告诉对方本端的 TCP 接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。

窗口大小的值是指,从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量。

例如,假如确认号是 701 ,窗口字段是 1000。这就表明,从 701 号算起,发送此报文段的一方还有接收 1000 (字节序号是 701 ~ 1700) 个字节的数据的接收缓存空间。

校验和(2个字节):

由发送端填充,接收端对 TCP 报文段执行 CRC 算法(看你数据正不准确),以检验 TCP 报文段在传输过程中是否损坏,如果损坏则丢弃。

检验范围包括首部和数据两部分,这也是 TCP 可靠传输的一个重要保障。

紧急指针(2个字节):

仅在 __URG __= 1 时才有意义,它指出本报文段中的紧急数据的字节数。

__URG __= 1 时,发送方 TCP 就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍是普通数据。

因此,紧急指针指出了紧急数据的末尾在报文段中的位置。

三次招手,四次挥手

建立连接(三次招手)

在这里插入图片描述

数据传输

在这里插入图片描述

关闭连接(四次挥手)

在这里插入图片描述

关闭连接过程

当客户A 没有东西要发送时就要释放 A 这边的连接,A会发送一个报文(没有数据),其中 FIN 设置为1, 服务器B收到后会给应用程序一个信,这时A那边的连接已经关闭,即A不再发送信息(但仍可接收信息)。 A收到B的确认后进入等待状态,等待B请求释放连接, B数据发送完成后就向A请求连接释放,也是用FIN=1 表示, 并且用 ack = u+1(如图), A收到后回复一个确认信息,并进入 **TIME_WAIT **状态, 等待 2MSL 时间。

为什么要等待呢?

为了这种情况: B向A发送 FIN = 1 的释放连接请求,但这个报文丢失了, A没有接到不会发送确认信息, B 超时会重传,这时A在 **WAIT_TIME **还能够接收到这个请求,这时再回复一个确认就行了。(A收到 FIN = 1 的请求后 WAIT_TIME会重新记时)

另外服务器B存在一个保活状态,即如果A突然故障死机了,那B那边的连接资源什么时候能释放呢? 就是保活时间到了后,B会发送探测信息, 以决定是否释放连接。(你按照线程的Lock.wait(long)方法思考就行了)

动图请参考:https://cloud.tencent.com/developer/article/1181764

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

five-five

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值