计算机网络之传输层

这一层是面试的重点。在这里总结一下。

首先先看一下传输层位于哪一层。

TCP

可以看到传输层主要有UDP和TCP两种协议。我们先来看一下较为复杂的TCP协议。TCP与UDP不同的是TCP是一个可靠数据传输协议。TCP中有几个比较重要的机制:(1)超时与重传机制 (2)流量控制机制 (3)拥塞控制机制。TCP包中的包头也有相应的字段用来实现相关字段。我们来看一下TCP包的包头。


我们来说一下几个字段存在的意义。

我们来说一下几个字段存在的意义。

1. seq number和 ack number用于实现超时和重传机制。同时拥塞控制也会用到。

2. receive window用于流量控制。

流量控制

流量控制存在的意义是使得发送方的发送速率和接收方的处理速率相匹配。避免出现发送方发送数据过快而接收方无法及时处理的问题。具体操作就是在接收方的ack包中带上receive window字段保证发送端发送的速率不至于过快。

超时与重传

在实现超时与重传时,tcp使用了ack和seq号来做相关处理。我们先来了解一下这个seq和ack的使用方法。实际上seq是代表当前包的序列号在发送端发送的时候带上,ack是接收端收到的包的序列号(实际上TCP的ack是指定的收到的包的下一个即期望收到的包的序列号)在接收端收到的时候返回给发送端表明这个包我收到了。如果接收端发送的序列号和发送端期望收到的不一样的话发送端就能知道发生了丢包。从而使用对应的机制来重传。超时重传的机制主要有两种:回退N帧和选择重传

回退N帧

回退N帧的本质就是使用累计确认的方式即我发了12345 5个包只要我收到了第五个包的ack就表明我收到了5之前的所有包。但是如果发生了失序的包比如1245少了一个3失序的包全部丢弃返回收到ack2的信息。所以回退N帧的N就是这里来的,即发送方要重传丢掉的包和之后的所有的包。看一个图就清楚了。

选择重传

选择重传则是针对每一个包进行ack,如果某个包超时还没有收到ack那么重传对应的包。对失序的包进行缓存。

TCP的重传机制

TCP借鉴了gbn和selective repeat的优点使用了带累计确认的选择重传。即对失序的包进行存储,同时返回累计确认的ack number。

拥塞控制

拥塞控制存在的意义是保证发送和接收方的速率不超过链路的承载量。避免出现使用速率过快,比如发送的数据包超过了链路承载的速率导致频繁丢包。在实现拥塞控制时,tcp使用了ack和seq号来做相关处理。

其实主要就是分为3个阶段:

1 慢启动阶段

cwnd设置为1个MSS,在这个阶段cwnd(congestion window) 指数形式增长,直到出现超时或三次重复ack或者到达设定阈值。到达阈值切换为拥塞避免阶段。超时进入慢启动阶段,三次重复ack进入快速恢复阶段。

2 拥塞避免阶段

在这个阶段cwnd线性增长,直到出现超时或三次重复ack。超时进入慢启动阶段,三次重复ack进入快速恢复阶段。

**3 快速恢复阶段**

cwnd设置为三次重复ack前的一半(reno)还有一种是tahoe这种处理方式直接将状态切换为慢启动。然后切换为拥塞阶段。如果超时切换为慢启动阶段。

著名的三次握手与四次挥手

tcp在建立连接的时候需要进行三次握手,在断开连接的时候要进行四次挥手。

具体流程见图

握手流程图

首先要搞清楚为什么需要三次握手建立连接。看了很多博客和回答,我个人总结的根本原因是两个:同步双方的信息更新当前的状态。如果我们使用两次握手会有什么问题呢?即A-> B发送SYN信息,B收到A的信息以后发送一个ACK回去就视为连接已经建立。

1.  资源的浪费

比如A->B发了一个SYN包。SYN超时后重传一个新的SYN和新的随机seq number。但是B收到旧的SYN包的时候会视为一个有效的请求并分配资源返回一个ACK给A。但是A已经不会理会这个旧的ACK了只会用新的SYN建立的连接进行通信。B就会傻傻的等一个永远不会发送信息的连接(届不到的爱恋)。出现这个问题的原因就是状态没有更新。B不知道A的状态已经变化了。如果使用三次握手机制A在收到一个旧的ACK的时候就会发RST告诉B这个链接已经不要了从而更新状态。

2. 协商SEQ

在超时重传机制里SEQ和ACK是实现机制的重要信息之一。通过三次握手可以同步双方的信息A告诉B说要用这个seq,B->A B->A说好我使用这个seq。这样就可以同步从A->B这个方向的seq。但是B->A也需要一组。但是在B->A这一步既可以确认A->B的seq也可以发送B->A的seq。因此本来应该四步的操作可以简化为3步。这样就可以同步两方的seq信息。

常见面试题

1.为什么要三次握手?

见上面的解析

2.SYN Seq Num的初始值是固定的吗?

不是的。是由一个初始序列号( initial sequence number ISN)生成器生成的。这个生成器会用一个32位长的时钟,差不多4µs增长一次,因此 ISN 会在大约 4.55 小时循环一次

(2^32位的计数器,需要2^32*4 µs才能自增完,除以1小时共有多少µs便可算出2^32*4 /(1*60*60*1000*1000)=4.772185884)

而一个段在网络中并不会比最大分段寿命(Maximum Segment Lifetime (MSL) ,默认使用2分钟)长,MSL 比4.55小时要短,所以我们可以认为 ISN 会是唯一的。

3. 为什么ISN要是随机的值?

1. 防止旧的连接的包对新的连接产生影响。比如有一个旧的连接的数据包滞留在链路中,等到属于他的连接关闭了才到目的地点。如果每次都是固定值,接收方可能将其视为当前连接的数据包。

2. 安全考虑,由于是随机的猜测将更加困难。如果攻击者没有办法监听流量产生一个seq在接收窗口的数据包就十分困难。

4.什么是SYN攻击

系统会维护一个半连接队伍。即接收方已经向发送方发送ack但是还没有收到回复的队列。攻击者可以伪造IP短时间大量发送SYN请求,收到请求后不发ack。而服务端还需要维护这些资源从而达到dos攻击的目的。

5. 为什么在前两次握手不可以带数据

主要是为了安全考虑,如果在前两次就可以带数据的话。服务器就需要分配资源存储这些还没有建立连接的对端发来的数据库。如果恶意攻击者发送大量SYN数据包就很容易成功实施dos攻击。

挥手流程图

这里可以看出来,在关闭连接的时候多了一次挥手流程。原因是在接收端收到FIN请求包的时候可能还在处理数据,比如还有数据没有发。因此并不能立刻关闭socket,只能发一个ACK包告诉请求发起端你的FIN请求我收到了。等到接收端处理完毕后才会发FIN。因此多了一次握手过程。这里有两个比较重要的状态一个是请求发起关闭连接端的TIME_WAIT的状态和收到关闭连接端的CLOSE_WAIT状态。

常见面试题

1 为什么要四次挥手?

见上文

2 为什么client要等 2个MSL再彻底关闭连接?

1. 为了防止最后一次挥手的ack包丢包,如果在TIMED_WAIT阶段受到重复的FIN包则会重发最后一个ACK包。2. 防止当前连接的数据包对下一个连接的影响,经过两根MSL可以认为链路中已经没有关于这个连接的数据包了。

3. server存在过多time-wait阶段的连接怎么处理?

1. 可以修改linux编译内核选项允许CLOSE_WAIT状态的端口重用 。2. 可以修改内核选项允许加速回收。

UDP

和TCP相比UDP就简单很多了。UDP是一个无连接的不保障可靠性的传输层协议。

UDP的包头

从包头可以看出UDP与TCP不同的是UDP多了一个length。UDP本质是基于包的协议,而TCP是基于流的协议。因此TCP才会有著名的粘包问题。并且UDP是不包含源IP和目的IP的。因此在传输层UDP复用机制与TCP不同。UDP针对目的IP和目的端口号相同的请求会由一个进程处理,而TCP会由两个来处理。

UDP的复用机制

TCP复用机制

你可能感兴趣的:(计算机网络之传输层)