传输层
在TCP/IP协议栈, 传输层有两个协议TCP和UDP. 传输层为相互通信的应用程序提供了逻辑通信
- TCP(Transmission Control Protocol) : 需要将要传输的文件分段传输, 需要建立会话, 能够实现可靠传输. 有流量控制功能
- UDP(User Data Protocol;) : 用户报文协议, 一个数据包就能完成数据通信, 不需要建立会话, 不需要流量控制. 进行不可靠传输.(用于DNS解析, 多播或广播)
1.传输层协议和其他协议间的关系
http - TCP:80; https - TCP:443; RDP - TCP:3389; FTP - TCP:21
应用层服务使用 TCP或UDP的端口侦听客户端请求, 客户端使用IP地址定位服务器, 使用端口定位服务, 可以在服务器网卡上设置只开放必要的端口, 实现服务器的网络安全.
传输层协议和网络层协议的主要区别 : IP协议提供主机之间的逻辑通信; TCP和UDP协议提供进程之间的逻辑通信
TCP端口 : 端口号具有本地意义, 即端口号只是为了标志本层计算机应用层的各进程.在因特网中不同计算机 的相同端口号是没有意义的. 例如 : 才访问web服务时, 服务器端访问的是80端口, 但是客户端的每一个浏览器页面都各自占用一个独立的端口, 用于接收从服务器返回的数据
端口范围 : 0-65535
熟知端口 : 0-1023
等级端口 : 1024-49151
客户端口 : 49152-65535
2.UDP
- UDP是无连接的, 即发送数据之前不需要建立连接
- 使用不保证可靠传输
- 面向报文, 没有拥塞控制, 很适合多媒体通信要求
- 支持一对一, 一对多, 多对一和多对多的交互通信
- UDP的首部开销小, 只有8个字节
伪首部 :网络层的首部的一些信息拿过来计算检验和,
3.TCP
-
TCP是面向连接的传输层协议
-
每一条TCP连接只能由两个端点, 每一条TCP连接只能是点对点的
-
TCP提供可靠交付的服务, 且有流量控制, 避免网络拥塞
-
TCP提供全双工工通信
-
面向字节流
TCP把连接作为最基本的抽象, 每一条TCP连接有两个端点, TCP连接的端点不是主机, 不是主机的IP地址, 不是应用进程, 也是不是传输层的协议端口. TCP连接的端点叫做套接字(socket). 端口号拼到IP地址即构成了套接字
即 : TCP连接 ::={socket1msocket2} = {(IP:port1), (IP2:port2)}
TCP报文段首部格式
序号 : 这个数据段的第一个字节是整段数据的第几个字节
确认号 : 告诉发送端, 下一次该发送第多少字节的数据了(接收端发送给发送端的TCP报文首部)
数据偏移 : 记录TCP报文段第多少字节后开始 是数据部分
URG : 告诉计算机数据的优先级较高; URG=1,在客户端会优先发
ACK : 若为0 , 确认号无效; 若为1, 确认号有效
SYN : 同步时要用到;syn=1,要建立会话; 同意后返回syn=1
PSH : 如果PSH=1, 说明当数据段到接收端时,不需要在缓冲区排队, 直接提交给应用程序
RST : 若RST=1, 说明TCP会话出现了严重的错误, 必须释放连接
FIN : 数据通信结束时,要释放连接, FIN=1
窗口 : 告诉另一方自己的接收缓存多大
校验和 : 校验首部和数据两部分, 要在首部前面加上12字节伪首部进行计算
紧急指针 : URG=1时才有用,指明了紧急数据的尾部在数据包中字节的位置
1>可靠传输
可靠传输的工作原理 : 停止等待协议(即发送完一组数据后, 等对方确认后再发送下一组数据).但在传输过程中会出现以下四种情况 :
- 无差错情况 : A发送M1给B, B返回确认M1消息;A发送M2给B, B返回确认M2消息; A发送M3给B, B返回确认M3消息
- 超时重传 :A发送M1给B, B丢弃掉有差错的报文, A等待一段时间后,发现B没有响应, 于是超时重传M1, 重复上面的过程
- 确认丢失 : A发送M1给B, B收到了, 但是返回给A的确认包丢失了. A超时重传M1,这时B因为已经接受过M1了, 所以直接丢弃重复的M1,重传确认M1, 然后A再发送M2
- 确认迟到 : A发送M1给B, B收到了, 但是返回给A的确认报走的慢, 于是A又超时重传M1,这次M2丢弃重复的M1,重传确认M1,然后继续. 最后A收到了之前迟到的那个M1, 但什么也不做
使用上述的确认和 重传机制, 我们就可以在不可靠的传输网络上实现可靠地通信. 这种可靠传输协议常称为 自动重传请求ARQ. ARQ表明重传的请求是自动进行的, 接受方不需要请求发送方重传某个出错的分组
停止等待协议的优点是简单, 但是缺点是信道利用率太低.可以用以下方案解决 :
- 流水线传输 : 发送方可连续发送多个 分组, 不必每发完一个分组就停顿下来等待对方的确认.由于信道上一直有数据不间断的传送, 这种传输方式可获得很高的信道利用率
- 连续ARQ协议 : 使用滑动窗口, 发送窗口, 发送方维持发送窗口. 每有一个确认信息返回, 窗口向右移
- 累计确认 : B收到数据后, 若有连续的数据, 直接确认一个连续序列的最后一个值, 滑动窗口就移动A中连续多个数据
如何实现可靠传输? 以字节为单位的滑动窗口
发送方和接收方协调好发送缓存和接收缓存后, 两边的缓存中各有一个滑动窗口, 发送方连续发送数据, 接受方在接收到几块数据后发送确认,接收窗口也向后移动, 应用程序就可以读取这部分数据了, 发送方根据返回来的确认号移动滑动窗口, 并将已经被确认的数据清除缓存. 如果中间有包丢失, 则接收端在返回确认时, 会发送一个SACK(选择性确认),告诉发送端哪一块缺失了, 这时候A接收到之后就不会再发送后面已发送的部分了.
超时重传时间的选择 : TCP每发送一个报文段, 就对这个报文段设置一次计时器. 只要计时器设置的重传时间到还没有收到确认, 就要重传这一额报文段
2>流量控制
解决通信两端处理速度不同的问题.
可以通过TCP首部窗口值的大小协调双方的接收窗口或发送窗口的大小.
流量控制往往指在给定的发送端和接收端之间的点对点通信量的控制, 他所要做的就是抑制发送端发送数据的速率, 一遍使接收端来的及接收
3>拥塞控制
尽管TCP有了滑动窗口这个看似完美的方案, 能够高效可靠的发送大量的数据, 但是如果在刚开始阶段就发送大量的数据, 仍然可能引发问题. 因为网络上有很多计算机, 可能当前的网络状态以及比较拥堵, 在不清楚网络状况的时候贸然发送大量数据, 只会让网络情况更差. TCP引入了慢开始,快重传和快恢复等方案来避免拥塞
1>慢开始. 发送方维持拥塞窗口cwnd
发送方控制拥塞窗口的原则是 :
- 只要网络没有出现拥塞, 拥塞拥塞窗口就再增大一些, 以便把更多的分组发送出去
- 只要网络出现拥塞, 拥塞窗口就减小一些,以减少注入到网络中的分组数
慢开始过程 : 拥塞窗口初始大小为1,首先先发一个数据包, 如果网络不拥塞(成功拿回确认), 第二次扩大拥塞窗口的大小为2,继续上述过程,然后到4,8,16. 16是慢开始门ssthresh的初始值, 拥塞窗口大小到16之后,为了避免拥塞进行加法增大, 增大到出现网络拥塞后, 重新进行慢开始, 并设置慢开始门ssthresh的值为出现拥塞时拥塞窗口大小的一半, 然后重新开始进行慢开始.
当TCP连接进行初始化时, 将拥塞窗口置为1. 图中的窗口单位不使用字节而使用报文段
但是拥塞避免算法并不能完全实现拥塞避免
2>快重传和快恢复
一条TCP连接有时会因为等待重传计时的超时而空闲较长时间,慢开始和拥塞避免无法解决这类问题,因此提出了快重传和快恢复的拥塞控制方法。
快重传算法首先要求接受方每收到一个失序的报文段后就立即发出重复确认. 而不要等待自己发送数据时才进行捎带确认. 这样做可以让发送方及早知道有报文段没有到达接收方
当发送端收到连续三个重复的确认时,就执行"乘法减小"算法, 把慢开始门限ssthresh减半, 但拥塞窗口的cwnd不设置为1, 而是设置为慢开始 门限ssthresh减半后的值, 然后开始执行拥塞避免算法(“加法增大”), 使拥塞窗口缓慢地线性增大
接受方收到不连续的数据包后, B连续发三次确认,确认号为开始断的地方. 如果都收到了, 说明网络不阻塞, 从新的慢开始值处(拥塞窗口的一般)开始快恢复(加法增大)
4.TCP的传输连接管理
传输连接有三个阶段, 即: 连接建立, 数据传送和连接释放. TCP连接的建立都是使用客户服务器方式.主动发起连接的应用进程叫做客户(client). 被动等待连接的应用进程叫做服务器(server)
1>建立连接过程 : 三次握手
TCP握手初始化一个连接的目标是 : 分配资源, 初始化序列号(通知peer对端我的初始序列号是多少), 知道初始化连接的目标, 可以简化为以下四次交互 :
- 1.client端首先发送一个SYN端告诉Server端我的初始序列号是X
- 2.Server端收到SYN包后回复给client一个ACK确认包, 告诉client说我收到了
- 3.接着Server端也要告诉client端自己的初始序列号, 于是server也发送一个SYN包告诉我的初始序列号是Y
- 4.Client收到后, 回复Server一个ACK确认包说我知道了
其实第2,3步可以合成一个数据包一起发送给Client, 这样建立一个TCP连接, 三次握手在进行最少交互的情况下完成了Peer两端的资源分配和初始化序列号交换
2>连接释放过程 : 四次挥手
TCP进行断开连接的目标是 : 回收资源, 终止数据传输. 由于TCP是全双工的, 需要Peer两端分别拆除自己通向Peer对端的方向的通信信道, 这样需要四次挥手分别拆除通信信道
- 1.Client发送一个FIN包告诉Server我已经没有数据要发送了
- 2.Server收到后回复一个ACK确认包说我知道了
- 3.然后Server在自己也没数据发送给Client后, Server也发送一个FIN包告诉Client我也已经没有数据要发给Client了
- 4.Client收到后, 就会回复一个ACK确认报说我知道了
到此, 四次挥手结束, 这个TCP连接就可以完全拆除了