计算机网络: 传输层

TCP 和 UDP 大家应该都听说过,也是面试中比较常见的内容,这两个协议都是在传输层的。这篇文章会讲述 TCP 和 UDP 里面实现的内容。

传输层是干什么用的

在学习一个东西之前我们应该先看要这个东西干嘛用的,传输层主要提供以下服务:

  1. 发送方将应用层的 Message 转成 Segment
  2. 接收方将接收到的 Segment 转成 Message,再给应用层
  3. 一般用于不同主机之间的进程交流

这里要和网络层对比一下,网络层主要用于两个主机(设备)间的交流,而传输层是用于进程之间的交流。

好像很简单呀,不就数据上传到下,下再传到上么?在理想情况下就是这么简单,但是实现总是不如意嘛。

多路复用

这也叫 Multiplexing,为什么要有这个东西呢?因为在计算机里每个进程向外面传数据都要通过不同 Socket 的,Multiplexing 就是将一个计算机里不同 Socket 数据集合到一个 Data 里再加上 Header,传给别的主机。别的主机收到后,再将这个大 Data 分成小块,将这些小块送到对应进程使用的 Socket 中,这个过程叫做 Demultiplexing,就是反过来用。

端口号

现在我们来想一个问题,上面 Multiplexing 里数据集合很容易呀,可以用一个数组存一存,那 Demultiplexing 怎么知道要送到哪个 Socket 呢?这就需要端口号了。

每个进程都会对应一个端口号,比如 8080 我们特别熟悉的,一般对应 Tomcat 进程或者别的本地服务器进程。每个进程向外发送的信息都会带有 <IP Adress, Port Number> 这样的组合,来告诉接收方我应该要将信息发给哪个进程。

下面是一个例子:

上面进完怎么将信息送到对应的进程,下面就来说说信息是怎么传输的,这就要说到我们很耳熟的两个协议——UDP,TCP。

UDP

特点

先来说说 UDP 的特点

  • Connectionless
    • 接收方和发送方都没有 Handshaking,也就我们所说的握手过程,后面会说到握手
  • Unreliable
    • UDP 的包丢了不会去恢复,丢了就丢了
    • UDP 的包是乱序的
    • 没有 Congestion Control
    • 没有 Flow Control

上面这两个 Control 会在 TCP 里讲,因为 TCP 要写的太多了。。。

格式

一个基础的 UDP 包格式如下

这里说一下 checksum 是啥。在发送数据之前,发送方会先根据整个 UDP segment 算一个 checksum 值,然后写在 Header 里。接收方拿到这个 segment 后,再根据拿到的 segment 算一个 checksum 去对比发送方算出来的 checksum 是否相等。如果相等就 OK,如果不等就不 OK,发送方要再重传这个数据包。

UDP 就没啥可讲了,你看 UDP segment format 就知道没多少东西,所以 UDP 的一个优点就是简单

Reliable Data Transfer

在说 TCP 之前,我们先了解一下 Reliable Data Transfer (rdt),因为 TCP 是这个东西的实现。要说的东西太多,只好再分一章放在前面写。这主要研究的是怎么发送更 Reliable 的数据。

数据传输的模型可以表示如下图所示。

这里的 udt 就是 Unreliable Data Transfer。rcv 是 receive。

rdt 1.0

我们先来想一个很简单的数据传输模型,如图

使用状态机可以表示如下

假如我们的 Channel 是可靠的(不发生丢包)的,那么就没问题了,也就没有后面的事情了。

rdt 2.0

一般 Channel 总是会有丢包的情况的,所以每次丢包后都需要 Sender 重新传那个 Packet。那怎么告诉 Sender 要重传呢?就要说到 ACK 和 NAK 了。

ACK = Acknowledgement,Receiver 告诉 Sender 我收到啦,一切 OK
NAK = Negative Acknowledgement,Receiver 告诉 Sender 我没收到,不 OK,你重传吧

所以 2.0 新加的功能就是

  1. 错误检测
  2. 接收方会发 Feedback 给发送方 (ACK, NAK)

2.0 的状态机图如下图所示

那是不是这样就解决所有问题呢?嗯,还没有,还有别的问题。比如,如果 Sender 没接收 ACK 或者 NAK 怎么办?ACK,NAK 有错误怎么办?下面来说说怎么解决这个问题。

解决 rdt 2.0 的问题

Stop and Wait

我们很容易想到一个简单的方案:我加个定时器 Timer,如果超时了说明没收到呗,再发一次。虽然可能有重复,不过接收方可以判断是否重复,然后再选择要不要这个 Packet。

我们初步的想法可以用下面这张图表示

但是这里有个隐藏的性能问题,我们每次都要等前一个 Packet 搞完了,才能发下一个好麻烦呀。假如网速 1Gbps,要传 8000 bits 的 Packet 就要时间:

D_trans = \frac{8000 bits}{10^9 bits/sec}=8 ms

假如 RTT (Round Trip Time) 是30

那么我们的利用率才

U_sender = \frac{L/R}{RTT+L/R}=\frac{0.008}{30.008}=0.00027

我们需要更高效的方法来传输 Packet 和 Feedback (ACK, NAK)。

更高效的方法解决 rdt2.0 问题

这个方法就是 Pipelining,Sender 先发一堆 Packet 给 Receiver,Receiver 再发一堆的 Feedback 回 Sender。

要怎么一堆发和一收一堆 Feedback 那等会再说,反正现在是不用每发完一个 Packet 再发下一个 Packet 了。

这种 Pipelining 方法具体有两种实现方式: Go-Back-N 和 Selective Repeat。

Go-Back-N

这个方案是先发一堆 Packet,Receiver 再发一堆 Feedback,如果其中有 NAK 或者丢失了 ACK,那么从那个 Packet 开始后面的 Packet 都要重新发一次,图示:

在上图中,因为 Sender 没有收到 pkt2 的 Feedback,所以 pk2, 3, 4, 5 都要再重新传一次,哪怕 pkt4, 5 都发了。

因为每次重传都是从第一个错误的 Packet 开始的,所以 Timer 只要一个就可以了,就是从最开始那个 Packet 开始计时。

Selective Repeat

这个就没上面的那么简单粗暴了,每个 Packet 都会有一个 Timer。每次 Packet Loss 时只会重传丢失的 Packet ,而不是全部都重传。

从上图可以看到,pkt2 丢失了,只需要重传 pkt 2 就好了。

还有一个问题

Selective Repeat 方法总是完美的,我们来想像下面的场景

上面是 pkt 3 丢失了,后面再传了一次 pkt 0,这个没什么问题,因为 pkt 3 后面会再重传的。再来看另一个场景

如果三个 Packet 都丢失了,那会从 pkt 0 开始重传,这就有问题了。看看 Reciever 那边第四个 0,这第四个到底是 Sender 的第一个 0 还是 Sender 的第四个 0 呢?这就是 Selective Repeat 的问题。

要解决这个问题只需要将 Window Size 小于 Sequence Number 就好了,比如这里 Window Size 最好小于 3.

TCP

现在回到传输层 TCP,TCP 的其中的 Reliable 特点就是上面说了一大堆的东西。当然它还有别的特点:

  • Point to Point: 一个 Sender 和一个 Receiver
  • Reliable (前面说完了),传输的包都是有顺序的
  • 有 Flow Control 和 Congestion Control
  • 双工: 数据可以在同一个连接里双向传递

Segment Format

这里面和 UDP 相比是多了那么点东西,其中 Sequence Number 和 Acknowledgement Number 是比较重要的。

  • Sequence Number: 用来标识 Stream 里的某个一个 Byte,通常来说 Sequence Number 是 32 位的
  • Acknowledge Number: 用于传递另一方下一个 Byte 对应的 Sequence Number
  • RTT: Round Trip Time: 用来设置超时的值

TCP 的 Reliable

参考前面的 Reliable。

这里要注意的一点是,TCP 重传会在收到同一个 Packet 的 4 次 ACK 后会立马开始重传,而不是要等到超时后再重传,相对来说会快一点。

Flow Control

TCP 是和应用层连接的,应用层也会用到传输层的数据,所以如果应用层取走数据的速度远低于传输层接收数据的速度就会出现 Buffer Overflow 了。

所以 TCP 需要一个机制来控制 Sender 传输速度。具体来说,当 Receiver 要发 Feedback 给 Sender 时,会加一项 rwnd,这个东西的值就是 Buffer 可用空间还有多少。

这样 Sender 就会根据这个 rwnd 来控制自己发送数据的速度了。

Connection Manager

这个就是我们所说的 “三次握手” 了。

  1. 客户端:你好服务器,我想连你可以么
  2. 服务器:你好客户端,你连我吧
  3. 客户端:那我发你数据 XXX 喽

Congestion Control

这个和 Flow Control 不同,这里要控制的是太多主机发送包给自己,而 Flow Control 只不过是控制传输层和应用层的数据流而已。

Congestion Control 方式有两种:Tahoe 和 RENO。他们都通过控制发送方的发送速度来实现 Congestion Control 的。原理如下:

  1. 发送方首先要线性方向来传数据,每次 cwnd (Congestion Window Size) 都会加 1,这个过程称为 Additive Increase
  2. 当出现丢包时,cwnd 会直接减一半,这个过程称为 Multiplicative Decrease

Slow Start, Congestion Avoidance

SS (Slow Start) 和 Congestion Avoidance (CA) 是 Congestion Control 的两个阶段。上面已经说了增加 cwnd 和减少 cwnd 的基本准则,而这两个阶段是在基本准则上的修改。

SS 阶段会先以指数倍地增加 cwnd

CA 阶段是指当 cwnd 达到阙值 (这里称为 ssthresh) 时,再以线性去增加 cwnd

所以先 cwnd = 1, 2, 4, 8, 16 (假如 16 是 ssthresh),然后 cwnd = 16, 17, 18, ...

丢包怎么办

刚刚只是说了怎么增加 cwnd,现在说说丢包后怎么减少 cwnd。当出现丢包后有两种响应方式:

  • Tahoe
    • ssthresh 设置成 cwnd / 2,然后 cwnd 重置为 1 MMS,再开始 SS 阶段
  • Reno
    • 将 ssthresh 设置成当前的 cwnd,然后将 cwnd 设置成当前 cwnd 的一半 (cwnd / 2)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容

  • 【计算机网络】传输层 传输层协议概述 传输层协议为运行在不同host上的进程提供了一种逻辑通信机制。使得端到端不需...
    666真666阅读 1,995评论 0 4
  • 1、TCP为什么需要3次握手,4次断开? “三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端...
    杰伦哎呦哎呦阅读 3,475评论 0 6
  • 运输层协议概述 从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是...
    srtianxia阅读 2,404评论 0 2
  • 目录 传输层与网络层一起构成了网络协议层次的核心。传输层架构在网络层提供的服务之上,把数据传递服务从两台计算机之间...
    开心糖果的夏天阅读 484评论 0 2
  • 我说了,凡事向内寻找,所以不能与他人太近,近了,简直就是一面照妖镜,你照出自己是个鬼来,照出你身上所有的缺点他几乎...
    木米2018阅读 138评论 0 0