liujijiang

计算机网络5:运输层

2020.05.20

网络层IP让你可以把消息从你的电脑上发送到别的电脑上,运输层的TCP和UDP可以让你从QQ上发送的消息传送到对方电脑的QQ上,而不是微信上,运输层在电脑之间通信的基础上进一步明确了是两个电脑的哪两个进程之间通信

简介

笔记内容:运输层特定,进程之间通信和端口的概念,简单讲UDP,主要讲TCP,TCP的停止等待协议,ARQ协议,三个重要问题:滑动窗口,流量控制,拥塞控制,然后TCP连接管理

通信的端点进程,计算机之间通信其实是计算机的进程之间的通信

复用和分用:

  • 复用:发送方多个进程使用相同的运输层协议传送数据,每个进程需要加上首部
  • 分用:接受方的运输层去掉报文的首部后准确的交给目的进程

iShot2020-05-20下午01.56.03-859ac2369f8b4d46bbedd34a6d127c41

网络层为主机之间提供通信,运输层为进程之间提供端到端的通信

各自特点:

  • TCP(传输控制协议):面向连接,全双工可靠信道
  • UDP(用户数据报协议):无连接,不可靠信道

UDP不需要连接,用户接收到UDP传输的文件后不需要确认
TCP需要先进行连接,传输完成后需要关闭连接

iShot2020-05-20下午02.27.00-793043327a0b4f82875bca72e4306434

端口

为了在复用和分用时区分进程

在TCP和UDP的首部都有源端口号和目的端口号

端口号最多为16位,一个计算机可以允许有65535个端口

IP加上端口号就可以在互联网中确定一个进程

分类

  • 服务器端使用端口号:
    • 系统端口号:计算机默认已经使用的端口号

iShot2020-05-20下午02.33.51-056b6f35ddb3418c975df44ced94f54c

  • 登记端口号:1024-49151
  • 客户端使用的端口号:短暂端口号,比如浏览器打开了一个网页就开了一个进程,关了网页进程也就随之关闭

UDP

特点:

  • 无连接:发送数据之前不需要建立连接
  • 尽最大努力交付:不保证可靠交付
  • 面向报文:把应用层传下来的报文加上首部就交给IP层,不合并也不拆分
  • 没有拥塞控制:网络出现拥塞也不会降低效率,适合IP电话或者视频会议
  • 支持一对一,一对多,多对一,多对多
  • 首部开销小:8个字节,TCP是20个字节

TCP

特点

  • 面向连接:应用TCP协议之前需要建立TCP连接,用完之后需要释放连接
  • 只支持点对点,一对一
  • 可靠交付:无差错,不丢失,不重复,按序到达
  • 全双工通信:允许通信双方任何时候向对方发送数据
  • 面向字节流:把进程要发送的数据看成一连串的无结构的字节序列

TCP协议会把进程发送的数据放到TCP缓存中,然后根据当前网络拥塞程度把缓存分成多好份进行发送

TCP连接

TCP协议是两个端点之间进行通信

TCP把每一个端点叫做套接字

套接字(socket):IP加上进程端口号

socket = IP地址:进程端口号

每一个TCP连接由两个socket确定:

TCP = (socket1,socket2)

可靠传输的工作原理

IP层是尽最大努力交付,所以TCP下面的网络层是不保证可靠性交付的,

停止等待协议

发送方发送完一个分组之后就进行等待,接受方接受校验无误后发送确认,发送方收到确认后继续发送下一个分组,所以无论分组是在过程中丢失还是接受后分组损坏,只有发送方没有收到确认就会再次发送。

超时重传:发送方发送分组后一段时间内没有收到确认就要重发之前的分组,所以要设置一个发送计时器,并且每次发送还要进行备份,而且要给每个分组进行标记。

无论是发送方收到重复的确认还是接受方收到重复分组都进行丢弃处理。

上面这个过程就是自动重传请求(ARQ)

信道利用率

停止等待协议的缺点就是利用率太低,发送完一个分组需要进行一段时间的等待

捕获-6288558606954ffc8de00f869719e7ce

捕获-caeaad8476ef4f86abe059fc12b4099c

连续ARQ协议

滑动窗口协议

捕获-1f85456da5c646b487b3cb841022b84c

窗口内的分组一起发送,并且接受方不是每一个分组都进行确认的,只对接受成功的最后一个分组进行发送确认,表示这个分组之前的分组都没问题

Go-back-N:窗口内五个分组一起发送,中间的三个分组接受失败,则需要发送方再一起发送中间的三个分组,叫做回退3个分组。

可靠传输机制:

  • 差错校验
  • 超时计时
  • 自动重传
  • 确认机制
  • 序号机制

TCP报文首部格式

捕获-de590c52c4734dd1bd76036e87fdc66b

  • 源端口号和目的端口号:各两个字节
  • 序号:4个字节,报文段的第一位占总报文的第几位
  • 确认号:4个字节,希望收到的下一个报文的序号,如果确认号位n,表示n-1位以及之前的全部收到了
  • 数据偏移:报文段起始处距离报文开始有多远
  • 保留:留到以后备用
  • 紧急URG:如果为1,表示这个报文段需要紧急传送
  • 确认ACK:为1时确认号才有效
  • 推送PSH:如果为1,则希望接收方尽快对这个报文段进行处理并回应
  • 复位RST:如果为1表示连接出现严重差错,需要断开连接
  • 同步SYN:在连接时同步序号
  • 终止FIN:为1时表示全部传送完,需要断开连接
  • 窗口:告诉接收方,发送方的发送的数据量
  • 校验和:检查首部和数据两部分
  • 紧急指针:如果为1,则指明了本报文段中的紧急数据字节数

TCP可靠传输的实现

发送方和接受方分别维护一个发送窗口和接受窗口,

发送窗口在没有收到确认前,把窗口内的报文都发送出去,所以窗口越大,效率越高

发送窗口接受确认后,窗口向前移动

发送缓存内数据情况:

  • 已经发送了等待确认
  • 在发送窗口内准备发送
  • 在发送窗口外等待发送

超时重传时间的选择:
运输层的时延变化比数据链路层大

新的RTTs:
捕获-f1e1d21cdb794dbfbaff527d9039d429

α推荐值是0.125

新的RTTd:
捕获-1a98036aae354860afb1c32ff23cabe7

β推荐值是0.25

超时重传时间RTO:
捕获-16b62d0b6f2a49c1a3bd66e3b5029618

Karn算法:
新RTO=2*旧RTO

选择确认SACK:

对比Go-back-N,不是记录最后一个确认的位后面的都要重传,而是缺少哪段报文旧重新传哪段报文

根据接收的报文的边界,推断缺失数据报文,然后只发送缺失部分报文

必须发生在超时重传之前,如果超时时间到了,就是全部重传

流量控制

让发送方发送的数据接收方能够来得及接受,而且不会造成网络拥塞

使用滑动窗口机制控制流量控制,通过动态调整首部的窗口字段的值

持续计时器:如果发送方一段时间发送窗口字段都是0,接收方会向发送方发送一个探测报文。

TCP缓存中数据发送时机

立即发送:

  • 缓存中数据达到最大缓存长度MSS
  • 发送方要求立即发送,比如push
  • 发送方的计时器到了

Nagle算法:
解决发送方窗口综合征问题:发送方每次只发送一个字节,一个字节也要封装分组发送,效率非常低

解决接收方窗口综合征问题:接收方告诉发送方要求窗口值为1

解决办法:第一个字节发送后开始等待确认,并且把收到的字节放进缓存,收到确认后发送缓存中的字节

接收方把收到的字节放进缓存中,攒到一定数量之后再处理

拥塞控制

拥塞控制是一直开启的

网络拥塞因素:

  • 缓存小
  • 带宽小
  • 处理慢

拥塞控制前提:网络能够处理现有的网络负荷

控制拥塞两种方法:

开环控制:设计网络时争取避免拥塞

闭环控制:

  • 监测拥塞在何时何地发生
  • 把拥塞信息传到可以处理的地方
  • 调整网络系统的运行来解决拥塞

四个拥塞控制算法:

  • 慢开始:确定网络负载能力和拥塞程度,窗口值用小增大测试负载能力
  • 拥塞避免
  • 快重传
  • 快恢复

使用窗口进行拥塞控制:
真正的发送窗口值=min(接受窗口值,拥塞窗口值)

TCP连接三个阶段

三次握手建立连接:

image-f5699bee575e42b0880249158b3176af

开始:两端都处于CLOSED状态

客户端主动打开连接,服务器端是被动打开连接的

第一次握手:
客户端型服务器端发出请求报文
同步位SYN=1,选择一个初始序号seq=x
这个报文不携带任何数据,但是消耗一个序号,然后客户端进入SYN-SENT(同步已经发送)状态。

第二次握手:
如果服务器端同意连接则向客户端发送一个确认报文
同步位SYN=1,确认ACK=1,确认号ack=x+1,自己的初始序号seq=y
同样这个报文不携带任何数据,也是消耗一个序号,然后服务器端进入SYN-SENT(同步已经发送)状态。

第三次握手:
客户端收到确认号后还需要向服务器端发送确认
确认ACK=1,确认号ack=y+1,自己的初始序号为x+1
客户端进入ESTABLISHED(已连接)状态

服务器收到确认号后也进入ESTABLISHED状态

第三次握手的必要性:

一种情况:如果客户端发送一个连接请求但是被阻塞在半路了,于是客户端又发送了一个请求并成功建立连接了,这时第一次发送的那个请求又到达了服务器端,服务器以为客户端又要建立连接于是向客户端发送确认

如果没有第三次握手:那么这时服务器端就又跟客户端建立了一个连接,然而客户端不会用这个连接发送信息,会造成服务器一直等待,造成资源浪费

如果有第三次握手:即使服务器发送了确认,但是由于客户端不会进行确认,就不会建立连接,也就避免了资源的浪费

TCP连接的释放

四次挥手进行连接的释放

image-0aae5994467c465396693affbfb71f98

客户端或者服务器端都可以主动进行释放连接

开始:两端都是ESTABLISHED状态

第一次挥手:
客户端向服务器端发送释放连接请求

终止控制位FIN=1,序号seq=u,u就是之前发送的数据的最后一个字节的序号加一

然后进入FIN-WAIT-1(终止等待),不携带任何数据,但是需要占一个序号

第二次挥手:

服务器端向客户端发送确认

确认ACK=1,确认号ack=u+1,自己的序号seq=v,v就是自己之前发送的最后一个数据字节的序号加一

然后服务器端进入CLOSE-WAIT(关闭等待)状态,客户端收到确认后进入FIN-WAIT-2状态

这时处于半关闭状态:客户端没有要向服务器端发送的数据了,但是服务器端可以向客户端发送数据

第三次挥手:

服务器向客户端发送报文释放连接

终止控制位FIN=1,确认ACK=1,ack=u+1,这是重复上次的确认,需要seq=w,w是服务器端在半关闭状态可能又向客户端发送了一下数据,w是这些数据的最后一个字节的序号加一

进入LAST-ACK(最后确认)状态

第四次挥手:

客户端收到报文后需要发送确认报文

确认ACK=1,确认号ack=w+1,序号seq=u+1

这时还没有释放连接,而是进入时间等待计时器计时状态,默认建议等两分钟然后才彻底断开连接

这个时间可以缩短

等两分钟原因

1 保证客户端发送的最后一次确认可以到达服务器端

2 防止出现已经失效的连接请求报文情况,跟为什么第三次握手一样

保活计时器

建立连接后为了防止客户端出错而服务器端还不知道的情况,服务器端如果两个小时没有收到客户端发送消息,就会每个75秒主动向客户端发送探测报文,如果连续发送10个客户端还没有反应,服务器端主动断开连接