• 传输层


    导学

    • 传输层属于TCP/IP协议的第三层,是面向通信的最高层,最面向用户的最底层

    • 传输层管理端到端的通信连接

    • 传输层本质是进程与进程的通信

      与在计算机原理中的进程通信的区别:Unix域套接字、共享内存是指计算机内部之间的进程通信,传输层是不同计算机之间的通信

    • 传输层使用端口(Port)来标记不同的网络进程
      端口(Port)使用16比特位表示(0~65535)
      常见端口号:

    • 传输层的两个重要协议是TCP、UDP

    UDP协议详解

    ◆ UDP(User Datagram Protocol: 用户数据报协议)
    ◆ UDP是一个非常简单的协议
    ◆ UDP是直接传输数据报,不合并、不拆分
    数据报(Datagram)就是应用层传输过来的数据

    ◆ UDP层次

    ◆ UDP报文结构

    UDP的特点

    • UDP是无连接协议
      UDP传输数据不需要提前建立连接

    • UDP不能保证可靠的交付数据
      “想发就发”,“无法保证数据在网络中是否丢失”

    • UDP是面向报文传输的

    • UDP没有拥塞控制
      UDP不管网络拥堵情况,对他来说直接把数据发出去就完事

    • UDP的首部开销很小
      对比TCP来说,UDP首部开销很小

    TCP协议详解

    ◆ TCP(Transmission Control Protocol: 传输控制协议)
    ◆ TCP协议是计算机网络中非常复杂的一个协议

    TCP协议的特点

    • TCP是面向连接的协议

    • TCP的一个连接有两端(点对点通信)

    • TCP提供可靠的传输服务

    • TCP协议提供全双工的通信

    • TCP是面向字节流的协议
      字节流,流入进程的字节

    TCP头部

    • 序号
      ◆ 长度32位,可表示0~2^32-1
      ◆ 一个字节一个序号
      ◆ 表示数据首字节序号

    • 确认号
      ◆ 长度32位,可表示0~2^32-1
      ◆ 一个字节一个序号
      ◆ 表示期望收到数据的首字节序号
      确认号为N:则表示N-1序号的数据都已经收到

    • 数据偏移
      ◆ 占4位:0~15,单位为:32位字
      ◆ 表示数据偏离首部的距离

    • TCP标记
      ◆ 占6位,每位各有不同意义

    • 窗口
      ◆ 占16位:0~2^16-1
      ◆ 窗口指明允许对方发送的数据量
      如果确认号是501
      窗口是1000
      那么就可以传输501~1500字节流

    • 校验和

    • 紧急指针
      ◆ 紧急数据(URG=1)
      ◆ 指定紧急数据在报文的位置

    • TCP选项
      ◆ 最多40字节
      ◆ 支持未来的拓展

    可靠传输的基本原理

    停止等待协议

    • 无差错的情况

    • 发送的消息在路上丢失了

    • 确认的消息在路上丢失了

    • 确认的消息很久才到

    小结:
    ◆ 每发送一个消息,都需要设置一个定时器(超时定时器)
    ◆ 停止等待协议是最简单的可靠传输协议
    ◆ 停止等待协议对信道的利用效率不高

    连续ARQ协议

    ◆ ARQ(Automatic Repeat reQuest:自动重传请求)
    ◆ 基于停止等待协议改进
    既然单个发送和确认效率低,可不可以批量发送和确认?
    使用滑动窗口批量传输,如下图单收到1、2确认信息后,窗口滑动2个窗口

    使用累计确认来减少确认报文,只要收到一个确认报文,就代表这前面的报文都已发送成功,如下图收到5确认报文,那就代表1-5发送成功,窗口滑动5个

    TCP协议的可靠传输

    ◆ TCP的可靠传输基于连续ARQ协议
    ◆ TCP的滑动窗口以字节为单位

    可用窗口=0

    可以看出,可靠传输的效率不高,怎么提高传输效率 ?

    选择重传机制
    如下图,假设收到了25、27确认

    ◆ 选择重传需要指定需要重传的字节
    ◆ 每一个字节都有唯一的32位序号
    ◆ 重传序号放在TCP选项(可选)

    一般是一段一段报文丢失,所以选择重传一般也不是指定每一个字节,而是指定一段字节的区间

    TCP协议的流量控制

    ◆ 属于TCP特有的功能
    ◆ 流量控制指让发送方发送速率不要太快
    ◆ 流量控制是使用滑动窗口来实现的

    窗口


    ◆ 占16位:0~2^16-1
    ◆ 窗口指明允许对方发送的数据量
    确认号为501
    窗口为1000
    则可传输501~1500

    • 通过窗口大小控制对方发送速率

      201表示期待下一次传输报文的开始序号
      如果要想传输快些,可调大窗口,如调为1000

      在上一次告知窗口为0后,如果告知窗口大小的报文没有传输给发送方,那会出现死锁的状态,发送方在等待,接收方也在等待

      怎么破?
      引入坚持定时器
      ◆ 当接收到窗口为0的消息,则启动坚持定时器
      ◆ 坚持定时器每隔一段时间发送一个窗口探测报文

    TCP协议的拥塞控制

    流量控制、拥塞控制的区别

    ◆ 流量控制考虑点对点的通信量的控制
    ◆ 拥塞控制考虑整个网络,是全局性的考虑
    报文超时则认为是拥塞

    拥塞控制的算法

    慢启动算法
    ◆ 由小到大逐渐增加发送数据量
    ◆ 每收到一个报文确认,就加一
    ◆ 呈指数增长,一直到慢启动阈值(ssthresh)

    拥塞避免算法
    ◆ 维护一个拥塞窗口的变量
    ◆ 到达 慢启动阈值(ssthresh)后,只要网络不拥塞,就试探着拥塞窗口调大
    ◆ 呈线性增长

    TCP连接的建立

    TCP标记

    ◆ 占6位,每位各有不同意义
    重新回顾TCP报文头各个字段

    • SYN Synchronization: 同步位,SYN=1 表示连接请求报文
    • ACK Acknowledgement: 确认位,ACK=1,确认号才生效
    • FIN Finish: 终止位,FIN=1 表示释放连接
    • 序号(sequence number):Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
    • 确认号(acknowledgement number):Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。

    不要将确认序号Ack与标志位中的ACK搞混了。确认方Ack=发起方Seq+1,两端配对。

    TCP连接的建立


    握手之前主动打开连接的客户端结束CLOSED阶段,被动打开的服务器端也结束CLOSED阶段,并进入LISTEN阶段。随后开始“三次握手”:
    (1)首先客户端向服务器端发送一段TCP报文,其中:

    • 标记位为SYN,表示“请求建立新连接”;
    • 序号为Seq=X(X一般为1);
    • 随后客户端进入SYN-SENT阶段

    (2)服务器端接收到来自客户端的TCP报文之后,结束LISTEN阶段。并返回一段TCP报文,其中:

    • 标志位为SYN和ACK,表示“确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接”(即告诉客户端,服务器收到了你的数据);
    • 序号为Seq=y;
    • 确认号为Ack=x+1,表示收到客户端的序号Seq并将其值加1作为自己确认号Ack的值;随后服务器端进入SYN-RCVD阶段

    (3)客户端接收到来自服务器端的确认收到数据的TCP报文之后,明确了从客户端到服务器的数据传输是正常的,结束SYN-SENT阶段。并返回最后一段TCP报文。其中:

    • 标志位为ACK,表示“确认收到服务器端同意连接的信号”(即告诉服务器,我知道你收到我发的数据了);
    • 序号为Seq=x+1,表示收到服务器端的确认号Ack,并将其值作为自己的序号值;
    • 确认号为Ack=y+1,表示收到服务器端序号Seq,并将其值加1作为自己的确认号Ack的值;
    • 随后客户端进入ESTABLISHED阶段。

    服务器收到来自客户端的“确认收到服务器数据”的TCP报文之后,明确了从服务器到客户端的数据传输是正常的。结束SYN-SENT阶段,进入ESTABLISHED阶段。

    在客户端与服务器端传输的TCP报文中,双方的确认号Ack和序号Seq的值,都是在彼此Ack和Seq值的基础上进行计算的,这样做保证了TCP报文传输的连贯性。一旦出现某一方发出的TCP报文丢失,便无法继续"握手",以此确保了"三次握手"的顺利完成。

    此后客户端和服务器端进行正常的数据传输。这就是“三次握手”的过程。

    一些重要概念:标记位、序号、确认号,(发送方)同步已发送、建立连接,(接收方)监听、同步已接收、建立连接

    为什么发送方要发出第三个确认报文呢?
    因为已经失效的连接请求报文传送到对方,引起错误。

    两次握手就建立连接,只要接收方回应了就建立连接了。
    如果是两次握手就建立连接,可能出现同样的请求报文发送了两次,就会建立两个连接。如下图所示:
    发送方首先发出1报文,但是由于各种原因,超时没有返回,于是发送方就发出2报文,2报文很快收到返回报文,建立起了连接。
    而后面1报文又到达接收方,由于是两次握手建立连接,所以接收方又返回报文,又建立了一个连接。

    三次握手建立连接时如何避免这个问题的呢?

    1报文到达接收方后,接收方虽然也会返回报文,但是发送方在上面已经发送了建立连接报文,所以迟返回的报文,发送方就要不会再进行连接了。

    tcp连接的四次挥手

    四次挥手的过程

    连接的释放必须是一方主动释放,另一方被动释放。以下为客户端主动发起释放连接的图解:

    注意:发送方不一定是主动结束的一方

    挥手之前主动释放连接的客户端结束ESTAB-LISHED阶段。随后开始“四次挥手”:
    (1)首先客户端想要释放连接,向服务器端发送一段TCP报文,其中:

    • 标记位为FIN,表示“请求释放连接“;
    • 序号为Seq=U;
    • 随后客户端进入FIN-WAIT-1阶段,即半关闭阶段。并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。
      注意:这里不发送的是正常连接时传输的数据(非确认报文),而不是一切数据,所以客户端仍然能发送ACK确认报文。

    (2)服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段TCP报文,其中:

    • 标记位为ACK,表示“接收到客户端发送的释放连接的请求”;
    • 序号为Seq=V;
    • 确认号为Ack=U+1,表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值;
    • 随后服务器端开始准备释放服务器端到客户端方向上的连接。
      客户端收到从服务器端发出的TCP报文之后,确认了服务器收到了客户端发出的释放连接请求,随后客户端结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段。

    前"两次挥手"既让服务器端知道了客户端想要释放连接,也让客户端知道了服务器端了解了自己想要释放连接的请求。于是,可以确认关闭客户端到服务器端方向上的连接了。

    3)服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文,其中:

    • 标记位为FIN,ACK,表示“已经准备好释放连接了”。注意:这里的ACK并不是确认收到服务器端报文的确认报文。
    • 序号为Seq=W;
    • 确认号为Ack=U+1;表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值。
      随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。

    (4)客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务器端发送一段报文,其中:

    • 标记位为ACK,表示“接收到服务器准备好释放连接的信号”。
    • 序号为Seq=U+1;表示是在收到了服务器端报文的基础上,将其确认号Ack值作为本段报文序号的值。
    • 确认号为Ack=W+1;表示是在收到了服务器端报文的基础上,将其序号Seq值作为本段报文确认号的值。
      随后客户端开始在TIME-WAIT阶段等待2MSL

    服务器端收到从客户端发出的TCP报文之后结束LAST-ACK阶段,进入CLOSED阶段。由此正式确认关闭服务器端到客户端方向上的连接。

    客户端等待完2MSL之后,结束TIME-WAIT阶段,进入CLOSED阶段,由此完成“四次挥手”。

    后“两次挥手”既让客户端知道了服务器端准备好释放连接了,也让服务器端知道了客户端了解了自己准备好释放连接了。于是,可以确认关闭服务器端到客户端方向上的连接了,由此完成“四次挥手”。

    与“三次挥手”一样,在客户端与服务器端传输的TCP报文中,双方的确认号Ack和序号Seq的值,都是在彼此Ack和Seq值的基础上进行计算的,这样做保证了TCP报文传输的连贯性,一旦出现某一方发出的TCP报文丢失,便无法继续"挥手",以此确保了"四次挥手"的顺利完成。

    等待计时器

    为什么要客户端要等待2MSL呢?

    • 为的是确认服务器端是否收到客户端发出的ACK确认报文。
    • 确保当前连接的所有报文都已经过期。

    当客户端发出最后的ACK确认报文时,并不能确定服务器端能够收到该段报文。所以客户端在发送完ACK确认报文之后,会设置一个时长为2MSL的等待计时器。
    MSL指的是Maximum Segment Lifetime(最长报文段寿命):一段TCP报文在传输过程中的最大生命周期。2MSL即是服务器端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的最大时长。

    服务器端在1MSL内没有收到客户端发出的ACK确认报文,就会再次向客户端发出FIN报文;
    如下图所示,如果服务器端在1MSL内没有收到客户端发出的ACK确认报文,就会再次向客户端发出FIN报文

    如果客户端在2MSL内,再次收到了来自服务器端的FIN报文,说明服务器端由于各种原因没有接收到客户端发出的ACK确认报文。客户端再次向服务器端发出ACK确认报文,计时器重置,重新开始2MSL的计时;

    所以,客户端要经历时长为2SML的TIME-WAIT阶段;这也是为什么客户端比服务器端晚进入CLOSED阶段的原因。

    否则客户端在2MSL内没有再次收到来自服务器端的FIN报文,说明服务器端正常接收了ACK确认报文,客户端可以进入CLOSED阶段,完成“四次挥手”。

    为什么“握手”是三次,“挥手”却要四次?
    TCP建立连接时之所以只需要"三次握手",是因为在第二次"握手"过程中,服务器端发送给客户端的TCP报文是以SYN与ACK作为标志位的。SYN是请求连接标志,表示服务器端同意建立连接;ACK是确认报文,表示告诉客户端,服务器端收到了它的请求报文。

    即SYN建立连接报文与ACK确认接收报文是在同一次"握手"当中传输的,所以"三次握手"不多也不少,正好让双方明确彼此信息互通。

    TCP释放连接时之所以需要“四次挥手”,是因为FIN释放连接报文与ACK确认接收报文是分别由第二次和第三次"握手"传输的。为何建立连接时一起传输,释放连接时却要分开传输?

    建立连接时,被动方服务器端结束CLOSED阶段进入“握手”阶段并不需要任何准备,可以直接返回SYN和ACK报文,开始建立连接。

    释放连接时,被动方服务器,突然收到主动方客户端释放连接的请求时并不能立即释放连接,因为还有必要的数据需要处理,所以服务器先返回ACK确认收到报文,经过CLOSE-WAIT阶段准备好释放连接之后,才能返回FIN释放连接报文。

    所以是“三次握手”,“四次挥手”。

    参考:https://www.cnblogs.com/AhuntSun-blog/p/12028636.html

    套接字与套接字编程

    ◆ 使用端口(Port)来标记不同的网络进程
    ◆ 端口(Port)使用16比特位表示(0~65535)
    ip和端口的组合,我们叫套接字socket

    ◆ 套接字(Socket)是抽象概念,表示TCP连接的一端
    ◆ 通过套接字可以进行数据发送或接收

    套接字编程

    网络套接字 VS 域套接字

    网络套接字,应用再跨机器、跨网络之间的通信,需要走一遍协议栈

    域套接字,应用再单机之间的通信,不需要走一遍协议栈

  • 相关阅读:
    JAVA 笔记二  转
    JAVA 笔记一  转
    在Eclipse中设置中文JavaDOC
    java session用法
    使用Session防止表单重复提交
    君の瞳に乾杯
    今夜では一人で雛祭り 03
    今夜では一人で雛祭り 02
    今夜では一人で雛祭り    001
    十年目のバレンタインデー   002
  • 原文地址:https://www.cnblogs.com/Uni-Hoang/p/13944496.html
Copyright © 2020-2023  润新知