目录
传输层的第三个功能:对收到的报文进行差错检测。(首部和数据部分)
一、传输层干了啥
上一章我们学了网络层,网络层干的事是将分组,通过路由器,从一个网络传递到另一个网络;
具体来说,是将一个分组从一个主机传递到另一个主机进行通信,是两台主机之间的逻辑通信。
然而,主机之间的通信,实质上是主机之间的两个应用程序进行通信(又称端到端的通信),
比如,A主机的QQ进程发送了一条消息给B主机的QQ进程,
传输层就负责具体这样的应用进程之间的逻辑通信。
那么,一台主机有很多形形色色的进程,相应地,传输层需要提供对应的协议吗?
答案是否。
这就是传输层的第二个功能——复用与分用。
复用:指的是发送方不同的应用进程都可以使用同一个传输层协议传输数据;
分用:指的是接收方的传输层收到数据后,应交付给指明的应用进程。
传输层的第三个功能:对收到的报文进行差错检测。(首部和数据部分)
因为网络层只负责检查IP数据报的首部是否有误,不检查数据,
所以传输层需要对传输层自己的首部和数据进行差错检测。
最后,传输层同时提供两种不同的协议:UDP & TCP。
对于网络层,有两种无法同时实现的协议:
1.面向连接的虚电路传输方式;
2.无连接的数据报传输方式。
网络层只能提供上述两种之其一。
但是,在传输层,可以同时存在面向连接的TCP和无连接的UDP。
综上,传输层提供的服务如下:
1.负责进程之间的逻辑通信
2.负责复用和分用
3.负责对收到的报文进行差错检测
4.提供TCP/UDP两种传输协议
二、传输层的寻址与端口,套接字,两种传输协议的区别
网络层有IP地址,我们通过IP地址可以找到主机;
而传输层有端口,我们通过端口来标识主机中的应用进程。
端口是传输层的服务访问点,应用层通过端口来访问传输层的服务。
端口号只有本地意义,在因特网中,不同计算机的相同端口是没有联系的。
端口长度为16bit,可以表示65536个不同的端口号。
我们通过范围将其分为两大类:
套接字
套接字Socket = (主机IP地址,端口号)
在网络中,套接字唯一标识了网络中的一个主机和它上面的一个进程。
TCP与UDP的区别
TCP:面向连接的传输控制协议
传送数据前必须建立连接,传输结束后需要断开连接。
只提供点对点,一对一的服务,不提供广播或多播服务。
可靠,
但是时延大,开销大,
适用于大文件。
UDP:无连接的用户数据报协议
传送数据之前不需要建立连接,收到UDP报文后也不需要确认。
不可靠,
速度快,实时性好,
适用于小文件。
三、UDP协议
UDP仅在IP的数据报服务之上增加了两个最基本的服务:复用分用,以及差错控制。
UDP优点:
1.无需建立连接。(无建立时延)
2.无连接状态。(不需要维护连接状态)
3.分组首部开销小。
4.速度快,实时性好。
UDP首部格式
当传输层从IP层收到UDP数据报时,就根据首部中的目的端口,把UDP数据报通过相应的端口上交给应用进程。
UDP校验使用了伪首部,只有在计算检验和时会出现。
四、TCP协议报文
TCP是在不可靠的IP层之上,实现的可靠数据传输协议。
主要特点八个字:
可靠 有序 不丢 不重
TCP优点:
1. 面向连接的传输层协议。
2.每条TCP连接只能有两个端点,是点对点的。
3.TCP提供可靠交付:保证传输的数据无措、有序、不丢失、不重复。
4.TCP采用全双工通信,通信双方可以一边发送一边接收。双方都拥有发送缓存和接收缓存。
发送缓存:
1.存放已发送但是还没收到确认的数据
2.存放还未发送的数据
接收缓存:
1.存放按序到达,但还未被应用程序读取的数据
2.存放不按序到达的数据
5.TCP面向字节流。
TCP报文段首部
1.源端口:发送TCP报文段的端口
2.目的端口:接收TCP报文段的端口
3.序号:TCP传送的字节流中,每个字节都按顺序编号。序号,表示本报文段所发送数据的第一个字节的序号。
4.确认号:期望收到对方下一个报文段的第一个数据字节的序号。
若确认号为N,则说明序列号到N-1为止的所有数据已经正确收到。
5.数据偏移(首部长度):TCP报文段的数据,距离报文段的起始有多远。
其实就是首部长度。
6.[六大控制位]
1.紧急位URG:
URG = 1时,表示此报文段中有紧急数据,不用在缓存里排队,应尽快传送。
配合紧急指针字段使用。
2.确认位ACK:
ACK = 1时,确认号有效。在连接建立后,应把所有传送的报文段的ACK位制1。
3.推送位PSH:
PSH = 1时,接收方应尽快交付接收应用进程,不用等到缓存填满再向上交付。
4.复位RST:
RST = 1时,表明TCP连接中出现了严重差错,必须释放连接,再重新建立传输连接。
5.同步位SYN:
SYN = 1时,表明这是一个连接请求/连接接受报文。
6.终止位FIN:
FIN = 1时,表明此报文段发送方数据已发完,要求释放连接。
7.窗口:发送本报文段的一方的接收窗口,即现在允许对方发送的数据量。
8.检验和:检验首部加数据
9.紧急指针:URG = 1时才有意义,指出本报文段中紧急数据的字节数。
10.选项:数据字段的最大长度。
11.填充字段:为了使整个首部为4B的整数倍。
五、TCP连接管理
TCP连接传输会经过三个阶段:
1.连接建立
2.数据传送
3.连接释放
其中:
连接建立的过程,我们称为3次握手;
连接释放的过程,我们称为4次挥手。
连接建立之三次握手
第一次握手:
首先,TCP连接采用客户机/服务器的方式,
主动发起连接建立的应用进程称为客户机(Client),
而被动等待连接建立的应用进程称为服务器(Server)。
连接还未建立时,客户机和服务器自身都是关闭的。
首先,客户端的TCP向服务器的TCP发送一个连接请求报文段,
这个报文段里是没有任何应用层的实际数据的,
但是这个报文段首部的SYN,也就是同步位,会设置为1,
表明这是一个连接请求报文。
当然,客户端会随机选择一个起始序号字段,设置为x。
然后发送给服务器。
第二次握手:
服务器的TCP收到连接请求报文段后,
如果同意连接,就为这段TCP连接分配TCP缓存和变量,以供传输。
并且服务器会反过来发送给客户端一个确认报文段。
这个确认报文段的首部中,
首先,因为他自己同意建立连接,所以同步位SYN标志为1;
其次,因为TCP规定,在连接建立后,所有传送的报文段都必须把确认位ACK制为1,表示我收到了你的请求,反馈一个确认信息,所以这个报文段的ACK标志位被制为1.
由于确认位置为了1,代表着服务器确认了某段消息。
而客户端发来的请求报文段中的序号seq是x,服务器也受到了,
代表着服务器已经收到了序号为x以前的所有报文。
所以服务器的确认位为1,确认号ack为x+1,代表接下来我想收到第x+1位的数据。
当然,发送过去的确认报文段自己也是没有应用层数据的,所以也需要产生一个随机序号seq = y。
第三次握手:
当客户机收到了确认报文段后,就可以传送数据了。
这个阶段,客户端也为该TCP连接分配缓存和变量。
但是,做事要有始有终,
既然服务器发来了确认报文段,但服务器并不知道客户端有没有收到,
所以客户端还需要发送一个确认的确认,
也就是向服务器发送一个确认报文段。
只有在连接请求,和接收连接请求的时候,同步位SYN才为1,
其余情况都是0.
所以客户端发送的确认报文中,先将自己的同步位SYN置为0。
然后因为是确认报文段,代表客户机已经收到了服务器发来的报文段,
而上一次服务器的报文段序号为随机产生的y,
所以新报文段中,首先确认位ACK为1,确认号ack则为y+1。
而对于服务器发来的确认报文,他的确认号是x+1,表明下一次,服务器希望收到第x+1的数据,
所以新报文段中,序号seq为x+1。
当然,这个报文段是可以携带数据的。
至此,TCP建立连接的三次握手结束,
客户端和服务器可以进行数据传送了。
SYN洪泛攻击
SYN洪泛攻击发生在传输层,这种方式利用了TCP的三次握手特性。
具体是怎么做的呢?
首先,攻击者作为客户端,对服务器发送连接请求,也就是第一次握手,
这是一次正常的握手;
然后,服务器会和客户端进行第二次握手。
但是,我们知道,在TCP第二次握手时,服务器会向客户端返回一个确认报文。
当服务器返回这个确认位为ACK的报文后,
该攻击者作为客户端,就不对其进行确认了。
导致这个TCP连接处于挂起状态,也就是半连接状态。
既然服务器收不到再确认报文,就会重复发送ACK给攻击者。
而每一个TCP挂起链接都没办法发完成三次握手,
这样会大大浪费服务器的资源,消耗CPU与内存,
最后,服务器可能死机,也就无法为正常的用户提供服务了。
解决方法为SYN cookie。
连接释放之四次挥手
天下没有不散的筵席。
参与一条TCP连接的两个进程中,任何一个都能终止该连接。
连接结束后,主机中的资源(缓存和变量)将被释放。
以客户机打算关闭连接为例:
第一次挥手:
首先,客户端发送一个连接释放报文段,并且停止发送数据,主动关闭这个TCP连接。
这个连接释放报文段中的FIN位被标识为1,代表客户端的数据已经发送完毕,要求释放传输连接。
同时,假设客户端上一次发送的数据序号为u-1,
客户端会设置起始序号字段,设置为u。
然后发送给服务器。
第二次挥手:
服务端回送一个确认报文段,
这个报文段中的ACK确认位为1,代表服务端已经收到了释放请求。
并且将ack设置为u+1,代表我下一个想要收到的字段序号为u+1。
同时,假设服务器上一次发送的数据序号为v-1,
自己的序号seq则为v。
至此,客户端到服务端这个方向的连接就释放了,但仅仅处于半关闭状态。
在这个阶段以后,服务器仍然可以向客户端发送数据;
第三次挥手:
服务端发完数据,就向客户端发送连接释放报文段。
其中,FIN位标识为1;
ACK位确认位标志为1;
设上一次服务器发送的数据序号为w-1,
seq序号为上一次发送的序号加1,也就是w;
由于在这个阶段,客户没有发送任何数据,
所以ack值仍然为u+1。
第四次挥手:
客户端收到服务器发来的连接释放报文段后,
需要回送一个确认报文段。
其中,ACK为1,代表确认收到;
seq = u+1,代表客户端将要发送报文段的序号;
ack = w+1.代表客户端已收到服务器发来的前w号数据,期待接收w+1号数据。
当然,连接还未关闭。
客户端有一个时间等待计时器,
需要等到这个计时器设置的2MSL,也就是最长报文段寿命的时间过去了,
才会彻底关闭连接。
为什么要等待一个2MSL的TIME-WAIT?
因为假如第四次挥手时,客户端发送的确认报文,服务器并没有收到,
那么服务器会再次给客户端发送请求连接释放报文段。
而客户端因为设置了一个TIME-WAIT,
所以有时间能收到这个新的连接释放报文段,并再次予以回馈。
不然客户端自己关闭连接后,
服务器重传的连接释放报文段,客户端无法收到,
那么服务器这边就无法正常关闭。
六、TCP可靠传输机制
TCP的任务是在IP层不可靠的,尽力而为服务的基础上,建立的一种可靠数据传输服务。
TCP需要保证接收方进程从缓存区读出的字节流和发送方发送的字节流完全一致,无顺序或重复,丢失等差错。
机制是:
1.校验——与UDP校验一样,增加伪首部;
2.序号——序号字段是一个报文段的第一个字节的序号;
3.确认——确认号是期望收到对方下一个报文段的数据的首字节序号;
使用累计确认。
4.重传——TCP的发送方在规定的时间内没有收到确认,就要重传已发送的报文段。
采用自适应算法,动态改变重传时间RTTs(加权平均往返时间)。
采用冗余确认:
每当比期望序号大的失序报文段到达时,发送一个冗余ACK,知名下一个期待确认字节的序号。
七、TCP流量控制
流量控制:让发送方慢一点,要让接收方来得及接收。
TCP通过滑动窗口机制实现流量控制。
在通信过程中,接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小,也就是接收窗口rwnd。
通过窗口字段来通知;
发送方的发送窗口 = min{接收窗口,拥塞窗口}
八、TCP拥塞控制
首先,拥塞控制和流量控制有什么区别?
流量控制是一个点对点的控制,涉及发送端和接收端。
流量控制要做的是控制发送端发送数据的速率,以便让接收端来得及接收。
是一个微观层面上的。
而拥塞控制是一个全局性,宏观的概念:
一个网络中,资源是有限的。
一旦对资源需求的总和大于了可用资源,
网络中就会有许多资源同时出现供应不足的情况,
这个时候整个网络的性能就会变坏,
网络的吞吐量就会随着负荷的增大而下降。
而拥塞控制就是让网络能够承载现有的网络负荷,
这设计所有主机,路由器,和其他与之相关的因素,
是一个全局性的控制。
一共有四种算法:
慢开始——拥塞避免;
快重传——快恢复。
1.慢开始
在TCP刚刚连接好,并开始发送TCP报文段时,
设置拥塞窗口为1,也就是一个最大报文段长度。
每收到一个对新报文的确认后,
就将拥塞窗口大小翻倍。
也称指数规律增长。
如第一个拥塞窗口为1,
收到确认后,第二个拥塞窗口就为2,
再次收到确认后,第三个拥塞窗口即可调整为4.
一直到拥塞窗口增大到了一个规定的慢开始门限ssthresh,也就是阈值,
这时候改用拥塞避免算法。
2.拥塞避免
每出现一次超时,也就是网络拥塞,就令门限为当前拥塞窗口大小的一半。
当拥塞窗口>=阈值时,通常改用拥塞避免算法。
这个算法不再进行指数增长,而是加法增大。
无论是慢开始,还是拥塞避免,只要检测到了拥塞,就设置门限为拥塞窗口的一半,
然后将拥塞窗口大小重置为1,执行慢开始算法。
3.快重传
快重传和快恢复是对慢开始和拥塞避免算法的改进。
当发送方连续收到三个重复的冗余ACK时,不再等待一个重传计时,而是直接重传对方尚未收到的报文段。
4.快恢复
当收到连续三个冗余ACK时,
还是将阈值设置为当前拥塞窗口的一半,
但是对于拥塞窗口本身,不再像拥塞避免,直接将窗口调整为1,
而是执行乘法减小,将拥塞窗口大小调整为新阈值,再执行拥塞避免算法。
这样灵活性更高,能提升网络性能。