TCP协议与UDP协议学习笔记

引子

今天正好是周末,刚好偶然翻到了之前学习计算机网络的时候做的关于TCP协议、UDP协议的笔记。TCP三次握手、四次挥手又是面试中的高频考点,正好自己最近也在准备各种面试,这里就总结一下TCP协议和UDP协议相关的知识点。

TCP协议与UDP协议

TCP协议和UDP协议是运输层的两个主要协议。

  • TCP:Transmission Control Protocol,传输控制协议
  • UDP:User Datagram Protocol,用户数据报协议

两种协议对比:

TCP协议UDP协议
面向连接:使用之前要建立连接,使用之后要释放连接。无连接,面向报文:使用之前不需要建立连接
提供可靠交付服务。使用TCP连接传送的数据,无差错、不丢失、不重复,并且有序。使用 尽最大努力交付,不保证可靠交付。
每一条TCP连接只能有两个端点,每一条TCP连接只能是 点对点 的。UDP支持一对一、一对多、多对一和多对多的交互通信。
TCP有拥塞控制UDP没有拥塞控制
TCP首部 前20字节固定,后面的 4n 个字节的“选项”可根据需要增加UDP首部开销小,只有 8 字节。
TCP提供 全双工通信 

TCP三次握手

首先介绍几个关键词:

  • seq:序号,Sequence Number。TCP连接传输的数据流中的每一个字节都按顺序编号,首部中的序号字段指本报文段所发送数据的第一个字节的序号。
  • 确认号:期待收到对方下一个报文段的第一个数据字节的序号。在谢老师的书中用了小写的 ack 表示。
  • ACK:确认位,ACKnowledgement。只有ACK=1的时候,确认号字段才有效。
  • SYN:同步位,SYNchronization。在连接建立时用来同步序号。当SYN=1,并且ACK=0时,表明这是一个连接请求报文段。若对方同意连接,则在响应的报文段中使 SYN=1 和 ACK=1。因此,SYN=1 就表示这是一个连接请求或连接接受报文。
  • FIN:终止位,FINis。用来释放一个连接,当 FIN=1 时,表明此报文段发送方的数据已经传输完毕,并要求释放连接。

下面,我们来看看TCP三次握手的示意图:

具体的流程:

刚开始客户端和服务端都处于 CLOSED 状态,而后服务端开启,处于监听(LISTEN)状态,等待客户端的请求。现在客户端也开启,准备请求连接。

  • 第一次握手:客户端向服务端发送一个请求连接报文,报文首部中 同步位SYN=1,同时序号位 seq会被指定一个客户端对应的初始值,这里记为 x。此时,客户端进入 SYN-SENT 状态。
  • 第二次握手:服务端收到请求报文后,如果同意连接,则向客户端回复确认。在确认报文中,同步位SYN和确认位ACK都被置为1,同时将客户端的序号 x 加1作为确认号(ack=x+1),序号位seq也会被指定为一个服务端对应的初始值,这里记为y。此时,服务端进入 SYN-RCVD 状态。
  • 第三次握手:客户端收到服务端的确认后,还要向服务端回复确认。确认报文中,ACK被置为1,同时将服务端的序号 y 加1作为确认号(ack=y+1),并且将自己的序号位值 x 加1作为新的序号位(seq=x+1)。回复确认动作完成后,客户端进入 ESTABLISHED 状态,当服务端收到客户端的确认后,服务端也会进入 ESTABLISHED 状态。

理解了上面这个流程后,这里有几个问题:

1、为什么要三次握手?两次不行么?

 客户端得到信息服务端得到信息
第一次握手 客户端发送正常,服务端接收正常
第二次握手客户端、服务端的发送、接收均正常 
第三次握手 客户端、服务端的发送、接收均正常

三次握手的目的之一是 使双方都能确认对方的存在,以及双方的发送、接受功能都正常。如上面的表格:

  • 第一次握手后,服务端接收到客户端的信息,服务端就能够知道 客户端的发送功能正常,以及服务端自身的接收功能正常。
  • 第二次握手后,客户端收到服务端的确认消息,就能知道自己之前发送的消息服务端接收到了。客户端就能够知道 客户端自己的发送、接收功能都正常,同时 服务端的发送、接收功能都正常。
  • 第三次握手后,服务端收到了客户端的确认,就知道服务端自己回复的确认消息客户端收到了。服务端也就能知道 服务端自己以及客户端的发送、接收功能都正常。

也就是,经过三次握手后,客户端、服务端双方才能确保 双方的发送、接收功能均正常,而两次握手则不行。

对于第三次握手,需要再确认一次的目的是,为了防止客户端已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

比如,第一次握手时,客户端的报文由于网络等原因,在途中滞留了一段时间,以至于在连接释放后才到达服务端。服务端误以为这是一次新的连接请求,就回复确认。如果没有第三次客户端的确认,那在服务端回复确认后,连接就建立了,然而客户端并不理睬服务端的确认,服务端就会一直等待客户端的数据。这样就白白浪费了服务端资源。

2、有没有可能“四次握手”?

如前面图中,标了 草莓红 的第二次握手阶段,服务端在向客户端回复的确认报文段,可以拆成两个报文段。

如上图,服务端可以先发送一个确认报文段(ACK=1,ack = x+1),然后再发送一个同步报文段(SYN=1,seq=y)。这样的过程就变成了四报文握手,但效果和三次握手是一样的。

3、三次握手过程中,可以携带数据么?

第三次握手时可以携带数据,第一次和第二次不行。

在TCP三次握手示意图中,我标 蓝色 的第三次握手可以携带数据。

TCP的标准规定:SYN报文段(即SYN=1的报文段)不能携带数据,而ACK报文段可以携带数据。如果ACK报文段不携带数据,则不消耗序号,否则需要消耗序号。

什么意思呢?意思就是,如TCP三次握手示意图,第三次握手时,序号seq=x+1。如果此时不携带数据,那下一个数据报文段的序号仍然为 seq=x+1。如果此时携带了序号差为 t 的数据,那下一个数据报文段的序号就要变为 seq = x + 1 + t 。

从另一个角度,在第三次握手时,客户端已经知道 客户端自己和服务端 的发送、接收功能都正常了,所以携带数据也没问题。

TCP四次挥手

上面请了TCP三次握手建立连接的过程,连接建立后,客户端服务端开始传递数据,数据传递完后,需要进行TCP“四次挥手”才能将连接释放掉。下面就讲一讲TCP四次挥手的过程。
 

具体的流程:

刚开是客户端、服务端都处于 ESTABLISHED 状态,并可以互传数据。假设此时客户端的数据已经传递完毕,准备关闭连接了。

  • 第一次挥手:客户端向服务端发送连接释放报文段,报文首部终止控制位 FIN=1,其序号记为seq=u(假定前面客户端已经发送的最后一个字节的序号是 u-1)。同时,客户端进入 FIN-WAIT-1 状态。
  • 第二次挥手:服务端收到客户端的连接释放报文后,会立即回复确认。确认报文首部 ACK=1,并将客户端的序号 u 加 1 作为确认号(ack=u+1),同时序号记为 seq=v(假定前面服务端已经发送的最后一个字节的序号是 v-1)。此时,服务端进入 CLOSE-WAIT 状态。客户端收到来自服务的确认后,就进入 FIN-WAIT-2 状态。此时,服务端仍然可以向客户端传送数据。
  • 第三次挥手:当服务端向客户端的数据传送完毕后,服务端也要向客户端发送连接释放报文。报文首部终止控制位 FIN和确认位ACK都被置为1,服务端还必须重复上次已经发送过的确认号 ack=u+1。同时,记现在的序号 seq=w(假定在客户端释放连接后,服务端又向客户端发送了 序号差为 w-v 的数据)。这时,服务端进入 LAST-ACK 状态。
  • 第四次挥手:客户端收到服务端的连接释放报文段,会立即回复确认。确认报文中,ACK=1,将服务端传来的序号加1作为确认号 ack=w+1,自己的序号也变为 seq=u+1(客户端发送的上一条报文的序号为 u,即第一次挥手的报文)。此时,客户端进入 TIME-WAIT 状态。当服务端收到确认报文后,服务端进入 CLOSED状态。

需要注意的是,上面第四次挥手,当客户端回复确认报文后,进入TIME_WAIT 状态。此时,TCP连接仍然没有被释放。当客户端回复完确认报文后,需要在 TIME_WAIT 状态等待一段时间(一般是2个最长报文段寿命,记为 2MSL,建议1MSL=2分钟),才会进入 CLOSED 状态。

这里,又有几个问题:

1、客户端为什么必须要在 TIME_WAIT 状态等待 2MSL 呢?

这里有两个理由:

  • 第一,保证客户端发送的最后一个ACK报文能够到达服务端。

这个ACK报文是有可能会丢失的,因而处在 LAST-ACK 状态下的服务端收不到客户端对已发送的 FIN+ACK 报文(第三次挥手)的确认。服务端会超时重传这个 FIN+ACK 报文段,接着客户端就能在 2MSL时间内收到这个重传的 FIN+ACK 报文段。接着客户端会重新回复ACK确认报文,并且重新计时 2MSL。这样,客户端和服务端就能正常进入 CLOSED 状态。

如果客户端在 TIME_WAIT 状态不等待,而是在发送完 ACK 报文后立即释放连接,如果此ACK报文段丢失,那就收不到服务端重传的 FIN+ACK报文,也就无法正常回复确认,这样可能造成服务端一直等待确认,无法正常进入 CLOSED 状态。

  • 第二,防止已失效的连接请求报文段出现在本连接中。

客户端再发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续时间内所产生的所有报文段都从网络中消失。这样,下一个新的连接中就不会出现旧的连接请求报文段。

总结

TCP三次握手、四次挥手面试也被问到过很多次了,自己也是看了很多次了。这一次,又仔细认真地对照着书籍学习了一遍,终于搞懂了其中序号、确认号的变化关系了。理解着去学习,又学到了很多。加油!

参考文档

1、《计算机网络》第七版,谢希仁 著,第五章

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值