TCP三次握手、四次挥手

这篇博客主要讲解TCP三次握手、四次挥手的过程,原理和原因

TCP提供一种可靠、面向连接、字节流、传输层的服务

什么是可靠,通信媒介可能会丢失或改变被传递的信息,当通信双方接受到错误的信息的时候,TCP必须有能力令其接受到正却的信息

接收方怎么才能知道自己接收到的信息是否有错误呢?通过差错校验码。差错校验码能检验出信息是否有错,但仅限于检验,并不能纠错

处理错误的信息一般有两种方法,一种是用差错校正码,比如前向纠错码,通过这个纠错码,可以纠正错误的信息,另外一种方法就是简单重新发送正确的信息,直到正确的信息最终被接收。第二种方法,称为自动重复请求(Automatic Repeat Request,ARQ),这也是TCP使用的方法

对于错误的信息,发送方需要重新发送正确的信息给接收方,那么问题来了,发送方怎么知道接送方有没有接受到信息呢?

接送方给发送放发信号以确定自己已经接收到了一个分组,这种方法称为确认(acknowledgment),或ACK

问题解决了吗?并没有。1)发送方对一个ACK应该等待多长时间?2)如果ACK丢失了怎么办?3)如果分组被接收到了,但是里面有错误怎么办?

第一个问题暂且不讨论,对于第二个问题,发送方不知道接收方到底是有没有收到信息,还是接收方的返回的ACK丢失了,所以它简单地再次发送原信息。对于第三个问题,当接收方接收到一个含有差错的信息时,它不发送ACK,等待发送方重发正确的信息

还有一个问题,当发送方不停地重新发送正确的信息时,接收方可能会收到重复信息,解决方法是序列号。每个唯一的信息都有自己新的序列号。接收方可以使用这个序列号来判断它是否已经见过这个信息,如果见过则丢弃它

现在,上面说的“可靠”有点靠谱了,TCP三次握手,四次挥手,基本就是围绕着可靠这二字展开的

TCP封装传输的信息,通常称为TCP报文段,或者分组,下面统一用“分组”代替上述的“信息”,显得专业一点

想知道TCP是如何是通过三次握手建立连接,通过四次挥手释放连接的,我们需要来看看TCP头部


序列号(Sequence Number)字段标识了TCP发送端到TCP接收端的数据流的一个字节,该字节代表这包含该序列号的报文段的数据中的第一个字节

什么意思呢?上面说过,TCP是面向字节流的,对于应用程序所给的数据,TCP必须把其转换成一组可以携带IP的分组。这些分组包含序列号,该序列号在TCP中实际代表了每个分组的第一个字节在整个数据流中的偏移。也就是说,每个分组的大小不一定是一样的,而且分组在发送的过程中,不一定会按发送的顺序到达,这就需要接收方根据偏移按顺序重新将乱序的分组排好。

所谓字节流,可以总结为八个字:大小不定,先来后到。大小不定,便是流,先来后到,便是序,而序列号,就是用来维护这两个性质的

为了建立一个TCP连接,需要完成以下步骤:

1、主动开启者(通常称为客户端)发送一个SYN报文段(即一个在TCP头部的SYN为字段置为1的TCP/IP数据包),并指明自己想要连接的端口号和它的客户端初始序列号(记为ISN(c))。通常,客户端还会借此发送一个或多个选项。客户端发送的这个SYN报文段称做段1

2、服务器也发送自己的SYN报文段作为响应,并包含了它的初始序列号(记作ISN(s))。该段称作段2。此外为了确认客户端的SYN,服务器将其包含的ISN(c)数值加1后作为返回的ACK数值。因此,每发送一个SYN,序列号就会自动加1。这样如果出现丢失的情况,该SYN段将会重传

3、为了确认服务器的SYN,客户端将ISN(s)的数值加1后作为返回的ACK数值。这段称作段3


这个过程要记住还是很容易的,但有没有想过,为什么要三次握手才能建立一个连接呢?

首先要知道一点,什么是连接,通信双方在交换数据之前和交换数据的时候都知道通信的对方是谁,这种状态的维持,就是连接

想象我们自己日常中的打电话,假如有A、B两人,A向B打招呼:“你好”,这时对于A来说,只要B给了个回应,就算建立通话了,而B也给了个回应:“你好”,这时A收到了回应,对于A来说,通话已经建立,而对于B来说,他要A给它一个回应才算建立连接,因为他不知道A到底有没有收到自己的回应(对于现实中的我们,此时对于B来说,通话已经建立了,因为他默认A收到了回应),当A再次回应B:“你今天。。。”的时候,对于B来说,通话才算建立

对于TCP来说,道理是一样的,建立连接双方都必须给对方发送自己的SYN和ISN,也都必须收到对方的ACK,一共四次握手,像这样


但显然中间的两次握手是可以合并的,合并之后就变成我们现在看到的TCP三次握手

所以三次握手,是建立TCP连接所需要的最少握手次数,再多的握手,也只是在原来的基础上增加更多的ACK,不仅不会增加可靠性,反而会浪费时间

那两次握手呢?发送方给接收方发送自己的SYN和ISN,接收方给发送方发送一个ACK,加上自己SYN和ISN

这样对于发送方来说,连接算是建立了,但对于接收方来说,因为发送方一直没发送一个ACK,所以接送方就一直重新发送自己的分组给发送方,直到收到发送方的ACK,所以两次握手是不行的

分组在发送中可能会丢失,这是至少需要三次握手的根本原因

再看看四次挥手的过程:

1、连接的主动关闭者发送一个FIN段指明接收者希望看到的自己当前的序列号。FIN段还包含了一个ACK段用于确认对方最近一次发来的数据

2、连接的被动关闭者将K的数值加1作为相应的ACK值,以表明它已经成功接收到主动关闭者发送的FIN。此时,上层的应用程序会被告知连接的另一端已经提出了关闭的请求。通常,这将导致应用程序发起自己的关闭操作。接着,被动关闭者将身份转变为主动关闭者,并发送自己的FIN。该报文段的序列号为L

3、为了完成连接的关闭,最后发送的报文段还包含一个ACK用于确认上一个FIN。


怎么样,这个四次挥手的过程跟我们上面四次握手的是不是很像?那为什么这四次挥手不像上面四次握手那样合并成三次挥手呢?

因为TCP支持半关闭的操作



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值