zoukankan      html  css  js  c++  java
  • TCP协议简介及其三次握手与四次挥手

    本篇博文是对参考文章的学习总结

    一、TCP介绍

    tcp协议之所以设计复杂,可以说它秉承的是“性恶论”。它认为网络环境天生就是恶劣的,丢包、乱序、重传、拥塞都是常有的事,一言不合就可能送达不了,所以只能从算法层面上来保证传输的可靠性。

    TCP包头格式

    其中源端口号和目的端口号是用来确定数据应该发往哪个应用层中的进程。

    序号是用来解决乱序的问题。

    确认序号用来确认发出去的包对方是否接收成功,不管有没有成功都应该有个回复,可以解决丢包问题,如果对方没有接收成功,则继续发送。TCP 是靠谱的协议,但是这不能说明它面临的网络环境好。从ip层来说,网络环境是复杂多变的,没有什么可靠性而言,而tcp所能做的就是尽最大努力交付,通过各种算法保证。如果丢包就重传,保证在tcp层面上努力保证可靠性。

    其中的状态位用来维持状态连接,因为TCP是面向连接的,所以根据状态位的变化,来维持连接状态。ACK表示回复,SYN代表建立一个连接,RST表示拒绝连接,FIN表示结束连接。

    窗口大小用来进行流量控制的,通信双方需要各自建立一个流量窗口,标识当前自己的处理能力,避免发送太快与太慢。流量控制主要针对的是通信双方。在保证流量控制的同时,针对网络环境的变化,还需要一定的拥塞避免处理能力,当网络环境拥堵时,就需要调整自己的发送速度来适应网络环境。拥塞避免主要针对的是网络环境。

    二、TCP三次握手

    当要建立一个连接的时候,刚开始,客户端处于closed状态,服务端处于listen状态。然后:

    1.第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号ISN(c)(这个序列号是为了后面的可靠传输做准备,是动态生成的,以防止网络攻击)。此时客户端处于 SYN_Sent 状态。

    2.第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s),同时会把客户端的 ISN + 1 作为 ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_REVD 的状态。

    3.第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 establised 状态。

    服务器收到 ACK 报文之后,也处于 establised 状态,此时,双方以建立起了链接。

    为什么要进行三次握手?

    握手要确定客户端与服务端均具有发送和接收消息的能力。三次握手的具体确认有如下几个方面:

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

    第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。    

    第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。

    三、TCP四次挥手

    刚开始双方都处于 establised 状态,假如是客户端先发起关闭请求,则:

    1.第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于CLOSED_WAIT1状态。

    2.第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 + 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于CLOSE_WAIT2状态。

    3.第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。

    4.第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 + 1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态。

    服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。

    为什么要四次挥手?

    第一次挥手:在客户端不准备发送数据时,调用自己的close方法,底层主动发送关闭连接信号,即FIN信号。

    第二次挥手:收到服务端此时可能还有数据没有发送完毕,需要进一步发送数据,所以先回复一个ACK,然后可能要等待一段时间。

    第三次挥手:等到服务端没有信息发送时,就调用自己的close方法,底层发送一个关闭连接信号。

    第四次挥手:客户端发送一个ACK信号,此时让服务端知道自己已经收到服务端发来的关闭信号。在这过程中等待2MSL时间就进入closed状态,2MSL时间后,服务端再发送消息,客户端就回复RST信号。

    四、整体状态迁移图

    参考:1.极客时间《趣谈网络协议》第11讲

       2.码农有道微信公众号连接:https://mp.weixin.qq.com/s/8t_KFtrrBkFyZKPJg_y6pw

  • 相关阅读:
    男子汉要响当当面对自己写出的程序
    北京天气变化,记下它
    面向对象的设计原则-类设计原则
    JSSCript打开X3,并设置IE窗口样式
    “做人做事”的信条
    工作角色的定位
    JS语法字典网友总结
    处理多个选择结果
    Jquery获得控件值的方法
    选择器
  • 原文地址:https://www.cnblogs.com/jianglinliu/p/11326255.html
Copyright © 2011-2022 走看看