浅谈三次握手,四次挥手

TCP
  1. 可靠性:校验和、去重、按序到达、确认应答、超时重发、连接管理、三次握手四次挥手、流量控制、拥塞控制,通过滑动窗口、快速重传、延迟应答和捎带应答来提高性能
  2. 面向连接:在发送数据前,通信双方必须在彼此间建立一条连接,所谓的连接就是客户端和服务器内存中保存的关于对方的信息,如IP地址、端口号等
  3. 面向字节流:他会处理IP层或以下层的丢包、重复以及错误问题。
三次握手四次挥手
  • TCP服务模型

一个TCP连接有一个4元组构成(两个IP地址和两个端口号),连接通常分为三个阶段:启动、数据传输、退出

一个完整的TCP连接是双向和对称的,数据可以在两个方向上平等的流动。给上层程序提供一种双工服务。

当TCP接收到另一端的数据时,它会发送一个确认,但这个确认不会立即发送,一般会延迟一会儿。ACK是累积的,一个确认字节号N的ACK表示所有直到N的字节(不包括N)已经成功被接收了。这样的好处是如果一个ACK丢失,很可能后续的ACK就足以确认前面的报文段了。

  • TCP头部

tcp

  1. 源/目的端口号:在TCP中用于确定双方进程
  2. 序列号:保温数据段中的第一个字节号
  3. 确认序号:该确认序号的发送方期待接收的下一个序列号(最后被成功接收的数据字节序列号加1),这个字段只有在ACK位被启用的时候有效
  4. 4位首部长度:以4bytes为单位,只有4位,最大为15,因此头部最大长度位60字节,最小为5,头部最小为20字节(可变选项为空)
  5. 6位标志位:
    URG:紧急指针是否有效
    ACK:确认序号是否有效
    PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
    RST:重置连接,将携带RST标识的称为复位报文段
    SYN:用于初始化一个连接的序列号(建立连接),通常将携带SYN标识的称为同步报文段
    FIN:该报文的发送方已经结束向对方发送数据
  6. 16位窗口大小:填的是自己的接收缓冲区中剩余空间大小,为了进行流量控制(解决双方速度不匹配导致丢包的问题)
  7. 16位校验和:发送端填充,CRC校验,接收端校验不通过, 则认为数据有问题,此处的检验和不光包含TCP⾸首部, 也包含TCP数据部分
  8. 16位紧急指针:标识哪部分数据是紧急数据
  9. 40字节头部选项
  • 注意:

当新建一个连接时,从客户端发送到服务端的第一个报文段的SYN位被启用,这称为SYN报文段,这时序列号字段包含了在本次连接的这个方向上要使用的第一个序列号,即初始序列号ISN,之后发送的数据是ISN加1,因此SYN位字段会消耗一个序列号,这意味着使用重传进行可靠传输。而不消耗序列号的ACK则不是。

当一个连接被建立或被终止时,交换的报文段只包含TCP头部,而没有数据。

状态转换

3+4

  • 服务端

[CLOSED -> LISTEN] 服务器端调用listen后进入LISTEN状态,等待客户端连接;
[LISTEN -> SYN_RCVD] 一旦监听到连接请求(同步报⽂段),就将该连接放⼊内核等待队列中,并向客户端发送SYN确认报⽂;
[SYN_RCVD -> ESTABLISHED] 服务端⼀旦收到客户端的确认报⽂,就进⼊ESTABLISHED状态,可以进⾏行读写数据了;
[ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接(调⽤用close),服务器会收到结束报⽂段,服务器返回确认报⽂段并进⼊CLOSE_WAIT;
[CLOSE_WAIT -> LAST_ACK] 进⼊CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据);当服务器真正调⽤用close关闭连接时,会向客户端发送FIN,此时服务器进⼊LAST_ACK状态,等待最后一个ACK到来(这个ACK是客户端确认收到了FIN);
[LAST_ACK -> CLOSED] 服务器收到了对FIN的ACK,彻底关闭连接.

  • 客户端

[CLOSED -> SYN_SENT] 客户端调⽤用connect,发送同步报⽂段;
[SYN_SENT -> ESTABLISHED] connect调⽤用成功,则进ESTABLISHED状态,开始读写数据;
[ESTABLISHED -> FIN_WAIT_1] 客户端主动调⽤用close时,向服务器发送结束报⽂段,同时进⼊FIN_WAIT_1;
[FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报⽂段的确认,则进⼊FIN_WAIT_2,开始等待服务器的结束报⽂段;
[FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报⽂段,进⼊TIME_WAIT,并发出LAST_ACK;
[TIME_WAIT -> CLOSED] 客户端要等待⼀个2MSL(Max Segment Life,报⽂文最⼤生存时间)的时间,才会进⼊CLOSED状态.

为什么要“三次握手,四次挥手”
  • 三次握手

换个易于理解的视角来看为什么要3次握手。

客户端和服务端通信前要进行连接,“3次握手”的作用就是双方都能明确自己和对方的收、发能力是正常的

第一次握手:
客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的

第二次握手:
服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。从客户端的视角来看,我接到了服务端发送过来的响应数据包,说明服务端接收到了我在第一次握手时发送的网络包,并且成功发送了响应数据包,这就说明,服务端的接收、发送能力正常。而另一方面,我收到了服务端的响应数据包,说明我第一次发送的网络包成功到达服务端,这样,我自己的发送和接收能力也是正常的

第三次握手:
客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。第一、二次握手后,服务端并不知道客户端的接收能力以及自己的发送能力是否正常。而在第三次握手时,服务端收到了客户端对第二次握手作的回应。从服务端的角度,我在第二次握手时的响应数据发送出去了,客户端接收到了。所以,我的发送能力是正常的。而客户端的接收能力也是正常的。

  • 为什么是三次握手?

从上面的过程可以看到,最少是需要三次握手过程的。两次达不到让双方都得出自己、对方的接收、发送能力都正常的结论。其实每次收到网络包的一方至少是可以得到:对方的发送、我方的接收是正常的。而每一步都是有关联的,下一次的“响应”是由于第一次的“请求”触发,因此每次握手其实是可以得到额外的结论的。比如第三次握手时,服务端收到数据包,表明看服务端只能得到客户端的发送能力、服务端的接收能力是正常的,但是结合第二次,说明服务端在第二次发送的响应包,客户端接收到了,并且作出了响应,从而得到额外的结论:客户端的接收、服务端的发送是正常的。

//一二三代表第几次握手

视角客收客发服收服发
客户端一+二一+二
服务端二+三二+三
  • 四次挥手

TCP连接是双向传输的对等的模式,就是说双方都可以同时向对方发送或接收数据。当有一方要关闭连接时,会发送指令告知对方,我要关闭连接了。这时对方会回一个ACK,此时一个方向的连接关闭。但是另一个方向仍然可以继续传输数据,等到发送完了所有的数据后,会发送一个FIN段来关闭此方向上的连接。接收方发送ACK确认关闭连接。注意,接收到FIN报文的一方只能回复一个ACK,它是无法马上返回对方一个FIN报文段的,因为结束数据传输的“指令”是上层应用层给出的,我只是一个“搬运工”,我无法了解“上层的意志”

  • 为什么建立连接是三次握手,关闭连接是四次挥手呢?

这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方是否现在关闭发送数据通道,需要上层应用来决定,因此,己方ACK和FIN一般都会分开发送。

“三次握手,四次挥手”完成过程
  • 三次握手

其实3次握手的目的并不只是让通信双方都了解到一个连接正在建立,还在于利用数据包的选项来传输特殊的信息,交换初始序列号ISN。

3次握手是指发送了3个报文段,4次挥手是指发送了4个报文段。注意,SYN和FIN段都是会利用重传进行可靠传输的。

3

  1. 客户端发送一个SYN段,并指明客户端的初始序列号,即ISN(client)
  2. 服务端发送自己的SYN段作为应答,同样指明自己的ISN(server)。为了确认客户端的SYN,将ISN©+1作为ACK数值。这样,每发送一个SYN,序列号就会加1. 如果有丢失的情况,则会重传
  3. 为了确认服务器端的SYN,客户端将ISN(s)+1作为返回的ACK数值
  • 四次挥手

4

  1. 客户端发送一个FIN段,并包含一个希望接收者看到的自己当前的序列号K,同时还包含一个ACK表示确认对方最近一次发过来的数据
  2. 服务端将K值加1作为ACK序号值,表明收到了上一个包。这时上层的应用程序会被告知另一端发起了关闭操作,通常这将引起应用程序发起自己的关闭操作
  3. 服务端发起自己的FIN段,ACK=K+1, Seq=L
  4. 客户端确认。ACK=L+1
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值