简约说——TCP

1 篇文章 0 订阅

TCP协议

一、TCP报文头

在这里插入图片描述

  • SYN =1 :表示希望建立连接,并在序列号区域进行初始值的设定。
  • ACK =1 :表示确认应答,意思是服务端收到你的建立连接请求了,且给你回复一个应答。其实这里不一定非得是服务端才能置成1,客户端和服务端谁都可以发送确认应答的报文,所以TCP 规定除了最初建立连接时的 SYN 包之外,该位必须设置为 1
  • 剩余4个的解释如下:
    1. URG:紧急指针(urgent pointer)有效。
    2. PSH:接收方应该尽快将这个报文交给应用层。
    3. RST:重置连接。
    4. FIN:释放一个连接。

二、什么是“连接”

都说TCP协议是面向连接的可靠传输协议,但是什么是连接呢?是为你连了根隐形网线吗?

不多说,上官方解释:

Connections: 
The reliability and flow control mechanisms described above require that TCPs initialize and maintain certain status information for each data stream.  
The combination of this information, including sockets, sequence numbers, and window sizes, is called a connection.

简单来说就是,**用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接。**是不是听起来还是很抽象?那我们再继续给它剥一层皮!首先从关键字Socket下手。

  1. Socket是什么

    由 IP 地址和端口号组成,是一个“四元组”,在linux中查看如下图

在这里插入图片描述

发现没,就是这样的一组东西:**IP : port IP : port

即客户端从一个端口发出来,服务端从一个端口接收,一旦确认这个路径后,它俩的数据传输就永远这样走。正因为这样的唯一四元组,才使得tcp有了“连接”的感觉。

  1. 序列号

    用来解决乱序问题。

  2. 窗口大小

    用来做流量控制。类似于现实用管道的直径,虽然也不是很贴切,主要是针对服务端的确认反馈问题,比如某段时间服务端很忙,收到了客户端发给自己的数据包后,没来得及返回确认包,客户端连续发了好几个后没收到确认包,为了安全考虑它需要停止发送等待服务端的返回确认,这里的“好几个”即窗口大小,可以根据实际情况自己制定,也可以使用默认大小。(当然客户端也不是一直傻等着,到达窗口后会启动一个计时器,如果计时器响了服务端还没返回确认包,客户端有必要怀疑链路是否异常中断,后续还会进行其他一系列操作,这里先不提及)

这下对“连接”清晰了吗?下面开始正餐,tcp连接的建立。

1、三次握手建立连接

在这里插入图片描述

(1)首先客户端向服务器端发送一段TCP报文,其中:

  • 标记位为SYN,表示“请求建立新连接”;序号为Seq=X(X一般为1);
  • 随后客户端进入SYN-SENT阶段。

(2)服务器端接收到来自客户端的TCP报文之后,结束LISTEN阶段。并返回一段TCP报文,其中:

  • 标志位为SYN和ACK,表示“确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接”(即告诉客户端,服务器收到了你的数据);
  • 序号为Seq=y;确认号为Ack=x+1,表示收到客户端的序号Seq并将其值加1作为自己确认号Ack的值;
  • 随后服务器端进入SYN-RCVD阶段。

(3)客户端接收到来自服务器端的确认收到数据的TCP报文之后,明确了从客户端到服务器的数据传输是正常的,结束SYN-SENT阶段。并返回最后一段TCP报文。其中:

  • 标志位为ACK,表示“确认收到服务器端同意连接的信号”(即告诉服务器,我知道你收到我发的数据了);
  • 序号为Seq=x+1,表示收到服务器端的确认号Ack,并将其值作为自己的序号值;
  • 确认号为Ack=y+1,表示收到服务器端序号Seq,并将其值加1作为自己的确认号Ack的值;随后客户端进入ESTABLISHED阶段。

说这么一堆什么意思呢?通俗来讲,两个人说话:

A -> B : 喂,在吗? (客户端发起建立连接请求,进入等待发送模式SYN-SENT

B听到后内心OS:“giao! 有人喊我,出于礼貌我得回复他啊~!” 于是B->A : 我在!咋了?(服务端收到请求并确认返回,进入等待接收模式SYN-RCVD

好了,现在思考一下,A没收到回复前,是不是不知道喊的这声B能不能听见?B回复后,如果A不再来一个回复,B不知道自己是不是变成哑巴了,或者A聋了(指B->A通信管道是坏的)。没有第三次握手的弊端

所以必须A在收到B的回复后再给B来一个确认收到的报文。 A->B : 好的我知道你在了!(客户端给服务端发送一个确认,进入稳定连接状态ESTABLISHED

这样A和B认为,这条路走的通而且很稳定,至此三次握手建立连接结束。

2、四次挥手断开连接

在这里插入图片描述

  • 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
  • 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSED_WAIT 状态。
  • 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
  • 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
  • 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
  • 服务器收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
  • 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。

这里一点需要注意是:主动关闭连接的,才有 TIME_WAIT 状态。

QA:为什么 TIME_WAIT 等待的时间是 2MSL?

MSL 是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为 TCP 报文基于是 IP 协议的,而 IP 头中有一个 TTL 字段,是 IP 数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减 1,当此值为 0 则数据报将被丢弃,同时发送 ICMP 报文通知源主机。

MSL 与 TTL 的区别:MSL 的单位是时间,而 TTL 是经过路由跳数。所以 MSL 应该要大于等于 TTL 消耗为 0 的时间,以确保报文已被自然消亡。

TIME_WAIT等待 2 倍的 MSL,比较合理的解释是:网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值