阅读 37

计算机网络分层以及TCP协议运输连接管理

计算机网络基础对于我们软件开发者来说是很重要的基础知识,不管是日常的开发,抓包,或者网络框架的学习等,计算机网络知识都是基础。而学习计算机网络分层次的体系结构也是最基本的,下面我们就来复习一下计算机网络的体系结构。

  • 计算机网络体系结构

    • 学习计算机网络的时候,我们一般把计算机网络分为五层协议体系结构,分别为应用层、运输层、网络层、数据链路层、物理层。
    • 计算机网络各层及其协议的集合我们称为网络的体系结构
    • 五层协议的体系结构只是为介绍网络原理而设计的,实际应用还是TCP/IP四层体系结构,下面来看看对比图:

    计算机网络体系结构对比图

    • 应用层(application layer)

      • 应用层的任务是通过应用进程间的交互来完成特定的网络应用,进程所指的就是主机正在运行的程序。应用层协议定义的是应用进程间通信和交互的规则(应用协议有很多,比如万维网应用的HTTP,电子邮件协议SMTP,文件传送协议FTP等);应用层交互的数据单元称为报文
    • 运输层(transport layer)

      • 运输层的作用是让两个主机中进程间之间的通信提供通用的数据服务传输服务,说白了就是在两个主机之间传输应用层的报文。一台主机不可能只有一个进程,所以运输层有复用和分用的功能,复用就是说应用层的多个进程可以同时使用传输层来传输数据,而分用则是指传输层可以分别把传输的数据给到对应的应用层进程

      • 运输层主要有两种控制协议:

        运输层控制协议 TCP(Transmission Contrl Protocol) UDP(User Datagram Protocol)
        特点 提供面向连接的、可靠的数据传输服务 提供无连接的、尽最大努力(best-effort)的数据传输服务
        数据传输单位 报文段 用户数据报
    • 网络层(network layer)

      • 网络层的作用是为分组交换网上的不同主机提供通信服务,在TCP/IP体系结构中网络层使用的IP协议,网络层把运输层传递过来的数据也就是报文段或者用户数据报封装成分组或包进行传送,分组也叫IP数据报
      • 网络层还有另一个作用就是使数据传输源主机的运输层传递的分组能够选择合适的路由器找到目的主机。
    • 数据链路层(data link layer)

      • 数据链路层的作用是把网络层传递下来的IP数据报组成帧(frame)数据在两个相邻节点的链路上传递,每一帧包含必要的数据和控制信息(同步信息、地址信息,差错控制等)
    • 物理层(physical layer)

      • 物理层所传递数据单位是比特,作用为将数据链路层的帧变成比特流在两个主机之间传递(作为传递的物理媒介双绞线,同轴电缆、光缆等并不在物理层的协议之内,而是在物理层协议下面,可以认为是第0层,具体看下图)。
    • 两个主机之间数据传递流程

      网络数据在各层之间的传递过程

      • 两个主机数据传递也可以用一个简单的例子来说明,就好比两个使用信来彼此联系,寄信人的信就好比是数据,信从最高层传递,也就是寄信人手里,每过一层就相当于包上一个新的信封,写上必要的、交由下一层处理的地址信息。包含多个信封的信件送到收信人手里,收信人从第一层信封拆起,每拆开一个信封后(按照每一层协议进行处理数据),传递到最后收信人取出发信人信件的信息,也就是传递的数据。
    • TCP/IP 体系结构

      • 我们现在提到的TCP/IP并不是单指TCP和IP这两个具体的协议,而是表示因特网所使用的整个TCP/IP协议族。TCP/IP协议可以为各式各样的应用提供服务,同时TCP/IP协议也允许协议在格式各样的网络构成的互联网上运行。

      TCP IP协议族示意

  • TCP协议的运输连接管理

    • 经过前面的网络分层了解,我们都知道运输层有两个重要的协议TCP和UDP,而UDP协议传输是无连接的、不可靠的,所以也就不存在连接管理这一说;而TCP协议是面向连接的,所以才会有连接管理。

    • TCP协议的主要特点

      • TCP是面向连接的运输层协议,好比打电话,通话前输入号码拨打,等待连接,打完后需要挂断电话。
      • 每一个TCP连接只能有两个端点,TCP连接只能是点对点的
      • TCP提供可靠的交付服务。还是打电话的例子,电话号码指定就是你需要找的人,打通了电话才能通话。
      • TCP 提供全双工通信,全双工通信双方既是发送方也是接收方,允许通信双方的应用进程在任何时候都能发送数据。
      • 面向字节流。TCP中的“流”指的是流入到进程或者从进程流出的字节序列。TCP并不管字节流的含义、大小,只保证传递的字节流和接收的字节流是完全一样的。
    • 通过TCP协议的特点,我们知道TCP是面向连接的协议,TCP传递的报文则是通过运输连接来处理的。TCP运输连接的建立和释放是每一次面向连接通信中必不可少的过程。

      • TCP运输连接的管理就是使运输连接的建立和释放都能正常的运行

      • 运输连接的三个阶段:连接建立,数据传送,连接释放

      • TCP 连接建立

        • TCP连接的建立采用客户服务器的方式。什么意思呢?也就是主动发起连接建立的应用进程叫做客户(client),而被动等待连接建立的应用进程叫做服务器(server)。
        • TCP连接的建立也叫“三次握手”建立连接,我们先看看TCP三次握手建立连接示意图:

        三次握手建立TCP连接示意图

        • TCP建立连接过程:首先连接未建立之前客户和服务器进程都处于关闭状态(CLOSE)。
        • 其次开始建立连接,A客户进程是主动打开连接的,B服务器进程则是被动打开连接,A和B两端首先创建传输控制块TCB(Transmission Control Block,TCB存储了每一个连接中的一些重要信息,如:TCP连接表,到发送和接收缓存的指针,到重传队列的指针,当前发送和接收的序号等),然后A向B发送请求报文段,这时TCP数据报文首部中的同部位SYN=1,初始序号seq=x(表示数据段开始的序号),TCP规定SYN=1的报文是不能携带数据的,但是要消耗一个序号,这时候A的状态变成同步已发送状态(SYN-SENT);B创建了TCB之后则会变成收听(LISTEN)状态。
        • B收到A发来的请求连接报文后,如果同意建立连接,则会向A发送确认报文。B向A发送的确认报文SYN位和ACK位都是1,确认序号为ack=x+1(前面A发送请求已经消耗了x序号),同时B发送的报文初始序号为y,这时B状态为同步收到(SYN-RCVD)状态。
        • 最后A在收到B的确认报文之后,还要再次向B发送一次确认连接的报文,A发送的再次确认报文段的ACK位为1,确认h号ack=y+1(前面B发送的初始序号已经消耗了y序号),下一个报文段初始序号seq=x+1(TCP规定ACK报文可以携带数据,但是如果不携带数据则不用消耗序号,所以这里序号仍然为x+1),这时候A的状态变成了已建立连接(ESTABLISHED)状态,TCP连接已经建立,B在收到再次确认报文也变成已建立连接(ESTABLISHED)状态。到此TCP连接建立过程完成。
        • 这就是TCP建立连接三次握手的过程
      • 通过前面的流程走下来,我们了解到TCP的三次握手就是A和B三次交互的过程最终建立了连接,到这里你可能会有一个疑问,为什么是三次握手建立连接,两次握手建立连接好像也是可行的

        • 三次握手的原因为发送的报文是会失效的,而三次握手就是为了防止已失效的请求报文突然又传送到服务端。还是上面的A和B例子,如果A发送请求报文赢网络滞后原因延迟让B接收到,本来A发送的报文已经失效,而B在延迟接收到该报文之后并确认与A连接,但是A已经认为发到B的报文已经失效,则不会再次发送报文到B,这时候B确认与A连接则一直砸等待A发送数据,则会造成B的资源白白等待A而浪费,所以多加一次确认握手,这时B没有收到再次确认则不会建立连接,避免出现资源浪费。
      • TCP连接释放

        • TCP经过三次握手建立连接之后,客户和服务器发送完数据之后,还需要释放连接,下面我们来分析一个TCP连接释放的过程。
        • TCP连接释放过程是四次握手,我们先看看过程示意图

        TCP连接释放过程(四次握手)

        • TCP连接释放过程:首先,A和B双方数据传输结束,此时他们都处于已建立连接(ESTABLISHED)状态,这时A进程先向TCP发出连接释放报文,并停止发送数据,主动关闭TCP连接,A此时进入终止等待1(FIN-WAIT-1)状态。这时A发送的连接释放报文终止控制位FIN=1,释放报文的序号seq=u(u应该等于A前面传递数据的最后一个字节序号加上1,这里不懂前面发送数据序号数值,直接用u代替),TCP规定即使FIN报文段不携带数据也是要消耗一个序号的。
        • B服务器的应用进程在收到A发送的连接释放报文后,即向A发出确认报文,然后B进入关闭等待(CLOSE-WAIT)状态,确认序号为ack=u+1,而B进程发送报文的序号seq=v(v理论上等于B前面传递数据的最后一个字节序号加上1,这里不懂前面发送数据序号数值,直接用v代替),此时A到B的连接已经断开了,但是此时TCP的连接处于半关闭(half-close)状态,因为B到A的连接还没有关闭(全双工通信),也就是说此时B向A发送数据,A还是要接收的,但是A已经不能在向B发送数据(注意数据和报文不是一个概念)。
        • A在收到B发送的确认报文之后就进入终止等待2(FIN-WAIT2)状态。
        • B在发送确认报文之后,并且已经没有数据发送给A,则B的应用进程就会通知TCP释放连接;B发出的连接释放报文段FIN=1,序号为seq=w(在半关闭状态B可以又向A发送了数据),确认号必须是和前面发出确认报文一样ack=u+1,此时B就进入了最后确认状态(LAST-ACK)状态。
        • A在收到B发送的释放连接报文段后,还必须在向B发出确认,发出的确认报文段ACK=1,报文序号为seq=u+1(同理FIN报文必须要消耗一个序号),ack=w+1,此时A进入到时间等待(TIME-WAIT)状态。此时TCP的连接还没有断开,A必须经过时间等到计时器设置的2MLS时间之后,才会进入到关闭(CLOSED)状态。
        • B只要收到了A发出的确认报文,就进入了关闭(CLOSED)状态。
        • 到此,这就是TCP连接释放四次握手的过程。

        想必你到此肯定会有疑问,前面A释放关闭过程的MSL是什么,为什么要等待2MSL时间呢?

        • MSL叫做最长报文段寿命,1MSL=2分钟,也就是说A发出确认释放报文到进入到关闭(CLOSED)状态需要4分钟时间。
        • 另一个是等待2MLS的原因:首先是为了保证A发送的最后一个确认报文能够到达B,在A发送的最后一个确认报文到B的过程中该报文有可能会出现丢失,此时B处于最后确认(LAST-ACK)状态,B接收不到A发出的确认报文则会超时重传四次握手的第二、第三次握手,也就是FIN+ACK报文,A收到之后就会再次发出确认释放连接报文到B,重置2MLS时间等待计时器,以此保证B能收到A发出的确认报文。其次,另一个原因就是在TCP连接管理中提到的防止失效的连接请求报文段出现,导致资源浪费。
      • 看到这里,你也许还是会有疑问,FIN,ACK,SYN这些都是啥,他们都是TCP报文首部的组成,TCP报文是个极其复杂的东西,这里就不做深入的讨论。

最后

TCP的三次握手和四次握手在面试中也是经常被问到的问题,通过这一篇文章,我又把大学课程的知识重新拾了回来,也希望对看到这篇文章的朋友有所帮助。文章中如果有错误,请大家给我提出来,大家一起学习进步,如果觉得我的文章给予你帮助,也请给我一个喜欢和关注。

关注下面的标签,发现更多相似文章
评论