传输层入门笔记

多路复用和多路分用

因为网络层只有一个IP协议,而应用层则有HTTP,SMTP等各种协议。因此为了将消息合并/分解就需要传输层进行多路复用/分用。
传输层入门笔记

多路分用

无连接分用—UDP

一个进程至少有一个端口号,一个端口号对应一个socket。
一个UDPsocket包含了SP(源端口号)和DP(目标端口号)两个标识。

面向连接分用—TCP

在运输层中面向连接的网络传输多使用TCP,而TCP套接字和UDP套接字之间有一个细微的差别,就是,TCP套接字是由一个四元组(源IP地址、源端口号,目的IP地址,目的端口号)来标识的。
注意:与UDP不同的是,两个具有不同源IP或源端口号的到达的TCP报文段将被重定向到两个不同的套接字。这也就是为什么TCP套接字需要四元组数据标识的原因,如果只用两元组就无法分别是否报文来自于同一个IP。
而为什么TCP需要重定向到两个套接字呢?原因如下:

当一个UDP服务器接收到一个UDP报文段时,它会根据收到的UDP报文段的源IP和源端口号,把数据发送回客户端,它并不需要创建一个新的套接字来处理该报文段;
而对于一个TCP服务器,当它接受一个连接时,它会产生一个新的套接字,然后通过新的套接字来与客户端通信,也就是通过新的套接字来把数据发送回给客户端。由于每一个连接都会产生一个新的套接字,所以具有不同的源IP或源端口号的连接就是一个不同的连接,对应着产生的新的不同的套接字。
—–计算机网络运输层之多路复用与多路分解

总结下来就是因为TCP需要建立连接。

UDP

UDP协议主要的工作有两个,一个是复用和分用,另一个就是简单的错误校验(一定程度上保证端到端的正确性)。由于是基于IP协议,并未增加过多的校验工作,因此UDP属于BEST EFFORT服务,也就是说消息段可能会存在丢失和非按序到达的情况。
另一方面,由于不需要握手连接也不用校验太多,UDP的传输延迟小,速度快,成为了其优势。

UDP消息段结构

传输层入门笔记
如图所示,UDP消息段主要是在原应用层消息上增加了2个Byte的头。分别包含了SP,DP,Len和校验和。

checksum校验和

校验和的原理是对消息视为16bit整数,然后求和按位求反,保存在checksum中。接收方再通过该和进行检查。这种校验方法说明,校验和不等则一定有错,校验和相等则可能没错。因此是一种简单的校验。

TCP

可靠数据传输原理

要求数据不错不丢不乱。不仅仅是针对传输层,网络层也有保证可靠数据传输的需求。
如下图所示,可靠数据传输的原理可以用有限状态机FSM来描述。
传输层入门笔记
红线上为条件event,红线下为执行的操作actions。

假设信道会产生位错误—目的:不错

如果信道会产生位错误,则可以利用:校验和,ACK/NAK(确认机制)和重传(ARQ)来保障错误。
rdt2.0
传输层入门笔记
如图所示为初步FSM。通过该图,可以看出sender会打包发送数据和校验和sndpkt,然后进入等待状态。receiver会接收rcvpkt(就是sndpkt),然后进行校验.如果成功,发送成功信号ACK并提取数据;如果失败,则发送NAK并继续等待。sender这边则根据收到的是NAK还是ACK来决定是重发还是进入新一轮数据发送。
rdt2.1
考虑到ACK和NAK信号也有可能产生错误。因此引入2.1版本,将发送数据编号并将ACK/NAK加上校验和,只有等到正确的ACK,sender才会进入下一状态,如果是错误的信号或者是NAK则继续重传。为什么要编号呢?—目的:不乱为了让receiver知道sender发的是哪个数据,避免重复接收相同数据。另一方面,由于sender是停等协议,因此只需要01两种状态就可以了。
传输层入门笔记
上图为sender的FSM。corrupt()用于检测回来的信号是否坏掉,如果坏掉则重发。
传输层入门笔记
上图为receiver的FSM。当sender发送0号消息时,receiver处于0号消息等待状态。此时,如果0号消息坏掉,则发送NAK,如果成功,发送ACK。接下来是等待消息1。这时候看sender,如果sender接受的0号消息的ACK是损坏的,那么sender会重发一个0号消息。这时候编号就有用了,处于等待1号消息的receiver接到了0号消息,那么他会继续发ACK,但不采取其他操作(右下角的循环状态)。这时sender会收到新的ACK进入消息1的发送,那么整个FSM就可以运行下去了。
rdt2.2
其实有了编号后,我们是可以把NAK状态取消的,只要把ACK的状态也编号,变为0/1就行。
传输层入门笔记
如上图。对比rdt2.1可以看到,对于发送了0号消息的sender,除非收到返回的0号ACK,其他ACK或者错误都会继续重发。而receiver也得到了简化,对等待0/1状态,如果不正确,则发送另一个(1/0)ACK。

假设信道会产生位错误,并且会丢包—目的:不丢

rdt3.0
这时候我们可以加入定时器,如果一段时间没反应则自动重发。receiver不用改动,只用改动sender。如下图。
传输层入门笔记

性能优化

传输层入门笔记
如上图所示,这是rdt3.0实际运行时的时间利用率,可以发现大量的时间被用在等待ACK当中,因此,为了改善性能,提出了如下图所示的流水线方法。
传输层入门笔记
即不采用之前的停-等模式,而不断的发新的。不过这就存在一个量的问题,不断发发多少个为好呢?发太多服务器接受不了也是浪费。而且发一个也要L/R的时间。因此引入了窗口的概念,即一次发多个,但是个数不能大于窗口的大小(N)。由此引入两种协议:GBN协议和SC协议。

GBN协议

即GO-BACK-N回退N帧协议。其思想是sender一口气发N=6个包,然后等。再看另一方,receiver接收时,采用累计ACK回复模式,即假使sender发过来0-5个包,但是中间3号包掉了,成功接到了其他包,这时候,receiver只会依次将ACK0,ACK1,ACK2发回去,由于没收到3号包,因此不发ACK3,并且对于接到的4-5号包也不要,直接丢弃。再看sender一方,假设ACK1传丢了,只收到了ACK0和ACK2,由于知道receiver是采用累计的模式,发过来ACK2就说明2以前的都受到了。因此sender会把3-5全部重发一遍。接着由于窗口N为6,因此还会接着发6,7,8号包,然后等。
先看窗口的示意图。
传输层入门笔记
再看sender的FSM图
传输层入门笔记
最后是receiver的FSM图
传输层入门笔记

SR协议

即Selective Repeat选择性重发协议。看到GBN协议我们发现对于成功到达的乱序包,receiver会丢掉不要,这就会造成浪费。因此我们可以在receiver设置缓存,将提前到达的包存起来,并发送对应的ACK(无累计模式),这样就是SR协议。
其窗口构成如下,相比GBN,我们设置了一个receiver的缓存窗口:
传输层入门笔记
详细的机制是,对于sender,一口气发N个,然后收到ACKx后,关闭对应的计时器(相比GBN,SC有多个计时器)。如果收到的ACK是base的(窗口最左边),则窗口右移。并发送蓝色部分。对应receiver来说,接到一个包,就发一个ACKx。如果发过来的包及之前的包都变成粉红色(全部连续了),就把这些包提取出来,传给上层,并移动窗口。考虑下,如果发回去个sender的ACKx丢失了,sender重发,这时候receiver接到后只要再发一个ACKx就好。如下图:
传输层入门笔记
值得注意的是,SR协议的两个窗口大小和包序号k应该满足
NS+NR2k

TCP的可靠数据传输

TCP的消息格式如下:
传输层入门笔记
其中sequence number和acknowledgement number就是sender和receiver的包号。
TCP的可靠数据传输采用了GBN和SR两种协议的混合。

sender

首先来看sender,这里引用GBN的sender窗口示意图说明。
传输层入门笔记
如上图,TCP的sender类似GBN,也是一次发送N个包,并在发送base包的时候启动计时器(只有一个计时器),(先说明下TCP的receiver也是采用累计ACK机制),然后等待。当收到ACKx时,将base置为x(将黄色变绿),并重置计时器。sender的重发机制是当超时才会重发,并且只重发第一个黄色的包,也就是base序号包(这与GBN不同),然后重置计时器。
进一步考虑,由于sender仅当超时时才重发,因此对丢包的情况反应较慢。改进方法就是快速重传机制。也就是说,当sender收到三个相同的ACKx时,就立刻重发,不等计时器超时。具体原因可以参考:TCP快速重传为什么是三次冗余ack,这个三次是怎么定下来的?
补充:在实际里面,包的序号不是1234,而是该包号=上一个包号+该包的bit数。

receiver

再看receiver
传输层入门笔记
receiver采用的是累计ACK机制,但是他也采用了SR的缓存机制,并由快速重传机制进行保障。即当receiver收到了012456,缺3时,他会在012时依次发送ACK012,然后由于缺3,他会先把456缓存起来,并针对456的消息分别回复缺失3号包,由此触发快速重传。然后若此时sender的计时器还没到,而receiver就收到了3号包,他会发送ACK6,这样sender就会直接开始发送7。
TCP的receiver还有一个特点就是收到一个包不立刻发送ACK,而是等一下,在这个时间内,如果由新的连续包进来就直接发新包的ACK,如果是乱序包进来,就立刻发缺失包的缺失信号。这样可以减少回复ACK的次数。

计时器时间的设定

计时器的时间首先要大于RTT才行,不过大多少,目前的算法时首先估计一个动态的EstimatedRTT,然后再估计一个RTT的变化范围DevRTT,则计时器时间可写为:
TimeOutInterval=EstimatedRTT+4DevRTT

TCP流量控制

TCP的receiver会在返回去的数据包中,告知sender自己缓存队列剩余空间。不过如果剩余空间满了,sender仍会发送一个小数据包用于保持通信不断开。

TCP的连接

三次握手

假设两个人在打电话,

  • C先说:“你能听见吗?”【C处于等待回复状态,该句丢失C重说,直至S回答】
  • S听见后说:“能,你能听见我说话吗?”(S知道C能说话了,不知道C能不能听见)【S处于等待回复状态,该句丢失S重说,直至C回答】
  • C听见后回答:“我也能听见你说话”(C知道S能听见也能说话了)【C进入会话状态,若该句丢失C不管,S继续处于等待回复状态,若不丢失,S处于会话状态
  • C开始说话:“巴拉巴拉”【C进入会话状态等待S的ACK状态,若丢失,C重发该句;若到达,S直接进入会话状态,并回复ACK】
    传输层入门笔记
    SYN标志位置一表示连接建议过程通信。

四次挥手

要挂电话了。

  • C先说:“我说完了,准备挂了”(C说完想挂电话,但是不知道S还要不要说)【C处于等待回复状态,该句丢失C重说,直至S回答】
  • S听见后(分两种情况,S没说完,S说完了)说:“好的(ACK)”(S知道C不说了,想挂电话,所以先回复一个ACK,表明知道C的意图了,但是自己是否要挂电话要另说)【正常的会话状态,如果该句丢失,C收不到会重发上句,然后S也会重发ACK】
    • (如果S还有话说,则存在)
  • S说:“我也说完了,那就把电话挂了吧?”【S处于等待回复状态,该句丢失S重说,直至C回答】
  • C回复说:“那挂吧”【C进入30s倒计时,防止此句丢失,30s后C离开】
    • S收到后离开。

传输层入门笔记
蓝圈部分可能在实际中会合并

TCP的拥塞控制

与流量控制不同,拥塞控制的对象是整个传输网络,而流量控制则是端对端的控制。
从整个网络来看,重发会造成资源的浪费,对网络造成负担。并且,考虑到网络是由多个路由器组成的,一旦某个路由器节点将数据包丢掉(丢包),那么这对整个“上游”的传输能力都是中浪费,这个包在上游的传输工作都白费了。因此我们要对sender设置合适的传输速率保证不发生拥塞。

拥塞的控制原理

拥塞的控制方法由两种。
一种是端到端的拥塞控制:由端系统观察丢包重传的情况,自动估计网络的拥塞程度。
另一种是通过网络辅助控制:通过在数据包中插入指示包,如0,1,2,指示(RM,资源管理包),3,4….这种方法,当指示包通过路由器时,路由器会把当前节点的拥塞情况标注到指示包中,如此,再通过receiver回传给sender,sender便可以改变传输速率。

TCP拥塞控制实现

TCP的拥塞控制引入了几个参数。
首先是拥塞窗口(CongWin),该窗口类比之前的滑动窗口大小,他控制了sender在一个RTT内能发送的数据包的大小。由于包号实际是由数据段大小标注的,因此通过将已经发送的包号LastByteSent与回传回来最新的ACK的包号LastByteAcked做差,就可以求出本次RTT中CongWin的大小了。
然后是网络拥塞的标志,丢包事件(也就意味着重发事件)的发生可以很好的表征网络拥塞程度,当丢包开始发生时,我们可以认为网络开始拥塞了。值得说明的是,丢包事件可能由超时和3次重复ACK导致,这在后面会产生不同的应对策略。
AIMD(Additive Increase Multiplicative Decrease)
即加性(线性)增,乘性(对半)减。由于要不断调整拥塞窗口大小,以保证处于合适的传输速率。我们会在每个RTT将拥塞窗口增加一个包的单位(MSS:最大报文段长度(Maximum Segment Size)),【加性增】一旦发送丢包事件,立刻将下个RTT的拥塞窗口长度减半。【乘性减】
慢启动
由于一开始传输时,拥塞窗口都设为一个很小的值,如1,如果采用AIMD则开始增长过慢。因此采用慢启动的策略,即,开始时CongWin为1,每个RTT的CongWin是上一个RTT的两倍。
如何结束慢启动呢?我们通过设置Threshold参数来规定拥塞窗口大小。当某次RTT的拥塞窗口(CongWin)要大于等于Threshold大小时,该次CongWin改为Threshold,下一次应用AIMD模式。
并且,Threshold的大小会动态变化,在发生丢包事件时,变为上次CongWin的一半。
传输层入门笔记
如上图所示,蓝线采用了慢启动模式,而黑线则是在发生丢包时采用了AIMD模式。
何时才有哪种模式呢?这个我们依据是什么导致了丢包事件。如果是3次ACK导致的重发(丢包),则采用AIMD模式,如果是TimeOut导致的重发,则采用慢启动模式。依据是如果能收到3次ACK说明网络还是有一定的传输能力的,所以不用立刻减为1。
伪码如下:
传输层入门笔记