共计 3796 个字符,预计需要花费 10 分钟才能阅读完成。
网络分层构造
思考最简略的状况:两台主机之间的通信。这个时候只须要一条网线把两者连起来,规定好彼此的硬件接口,如都用 USB、电压 10v、频率 2.4GHz 等,这一层就是物理层,这些规定就是物理层协定。
咱们当然不满足于只有两台电脑连贯,因而咱们能够应用交换机把多个电脑连接起来,如下图:
这样连接起来的网络,称为局域网,也能够称为以太网(以太网是局域网的一种)。在这个网络中,咱们须要标识每个机器,这样才能够指定要和哪个机器通信。这个标识就是硬件地址 MAC。
硬件地址随机器的生产就被确定,永久性惟一。在局域网中,咱们须要和另外的机器通信时,只须要晓得他的硬件地址,交换机就会把咱们的音讯发送到对应的机器。
这里咱们能够不论底层的网线接口如何发送,把物理层抽离,在他之上创立一个新的档次,这就是数据链路层。
咱们仍然不满足于局域网的规模,须要把所有的局域网分割起来,这个时候就须要用到路由器来连贯两个局域网:
然而如果咱们还是应用硬件地址来作为通信对象的惟一标识,那么当网络规模越来越大,须要记住所有机器的硬件地址是不事实的;
同时,一个网络对象可能会频繁更换设施,这个时候硬件地址表保护起来更加简单。这里应用了一个新的地址来标记一个网络对象:IP 地址。
通过一个简略的寄信例子来了解 IP 地址。
我住在北京市,我敌人 A 住在上海市,我要给敌人 A 写信:
- 写完信,我会在信上写好我敌人 A 的地址,并放到北京市邮局(给信息附加指标 IP 地址,并发送给路由器)
- 邮局会帮我把信运输到上海市当地邮局(信息会通过路由传递到指标 IP 局域网的路由器)
- 上海市当地路由器会帮我把信交给敌人 A(局域网内通信)
因而,这里 IP 地址就是一个网络接入地址(敌人 A 的住址),我只须要晓得指标 IP 地址,路由器就能够把音讯给我带到。在局域网中,就能够动静保护一个 MAC 地址与 IP 地址的映射关系,依据目标 IP 地址就能够寻找到机器的 MAC 地址进行发送。
这样咱们不需治理底层如何去抉择机器,咱们只须要晓得 IP 地址,就能够和咱们的指标进行通信。这一层就是网络层。网络层的核心作用就是提供主机之间的逻辑通信。
这样,在网络中的所有主机,在逻辑上都连接起来了,下层只须要提供指标 IP 地址和数据,网络层就能够把音讯发送到对应的主机。
一个主机有多个过程,过程之间进行不同的网络通信,如边和敌人开黑边和女朋友聊微信。我的手机同时和两个不同机器进行通信。
那么当我的手机收到数据时,如何辨别是微信的数据,还是王者的数据?那么就必须在网络层之上再增加一层:运输层:
运输层通过 socket(套接字),将网络信息进行进一步的拆分,不同的利用过程能够独立进行网络申请,互不烦扰。
这就是运输层的最实质特点:提供过程之间的逻辑通信。这里的过程能够是主机之间,也能够是同个主机,所以在 android 中,socket 通信也是过程通信的一种形式。
当初不同的机器上的利用过程之间能够独立通信了,那么咱们就能够在计算机网络上开发出形模式式的利用:如 web 网页的 http,文件传输 ftp 等等。这一层称为应用层。
应用层还能够进一步拆分出表示层、会话层,但他们的实质特点都没有扭转:实现具体的业务需要。和上面的四层相比,他们并不是必须的,能够归属到应用层中。
最初对计网分层进行小结:
- 最底层物理层,负责两个机器之间通过硬件的间接通信;
- 数据链路层应用硬件地址在局域网中进行寻址,实现局域网通信;
- 网络层通过形象 IP 地址实现主机之间的逻辑通信;
- 运输层在网络层的根底上,对数据进行拆分,实现利用过程的独立网络通信;
- 应用层在运输层的根底上,依据具体的需要开发形模式式的性能。
这里须要留神的是,分层并不是在物理上的分层,而是逻辑上的分层。通过对底层逻辑的封装,使得下层的开发能够间接依赖底层的性能而无需理睬具体的实现,简便了开发。
这种分层的思路,也就是责任链设计模式,通过层层封装,把不同的职责独立起来,更加不便开发、保护等等。
TCP 面向字节流个性
TCP 并不是把应用层传输过去的数据间接加上首部而后发送给指标,而是把数据看成一个字节 流,给他们标上序号之后分局部发送。这就是 TCP 的面向字节流个性:
- TCP 会以流的模式从应用层读取数据并存放在本人的发送缓存区中,同时为这些字节标上序号
- TCP 会从发送方缓冲区抉择适量的字节组成 TCP 报文,通过网络层发送给指标
- 指标会读取字节并存放在本人的接管方缓冲区中,并在适合的时候交付给应用层
面向字节流的益处是无需一次存储过大的数据占用太多内存,害处是无奈晓得这些字节代表的意义,例如应用层发送一个音频文件和一个文本文件,对于 TCP 来说就是一串字节流,没有意义可言,这会导致粘包以及拆包问题,前面讲。
牢靠传输原理
后面讲到,TCP 是牢靠传输协定,也就是,一个数据交给他,他必定能够残缺无误地发送到指标地址,除非网络炸了。他实现的网络模型如下:
对于应用层来说,他就是一个牢靠传输的底层反对服务;而运输层底层采纳了网络层的不牢靠传输。尽管在网络层甚至数据链路层就能够应用协定来保障数据传输的可靠性,但这样网络的设计会更加简单、效率会随之升高。把数据传输的可靠性保障放在运输层,会更加适合。
牢靠传输原理的重点总结一下有:滑动窗口、超时重传、累积确认、抉择确认、间断 ARQ。
进行期待协定
要实现牢靠传输,最简便的办法就是:我发送一个数据包给你,而后你跟我回复收到,我持续发送下一个数据包。传输模型如下:
这种“一来一去”的办法来保障传输牢靠就是进行期待协定(stop-and-wait)。不晓得还记不记得后面 TCP 首部有一个 ack 字段,当他设置为 1 的时候,示意这个报文是一个确认收到报文。
而后再来思考另一种状况:丢包。网络环境不牢靠,导致每一次发送的数据包可能会失落,如果机器 A 发送了数据包失落了,那么机器 B 永远接管不到数据,机器 A 永远在期待。
解决这个问题的办法是:超时重传。当机器 A 收回一个数据包时便开始计时,工夫到还没收到确认回复,就能够认为是产生了丢包,便再次发送,也就是重传。
但重传会导致另一种问题:如果原先的数据包并没有失落,只是在网络中待的工夫比拟久,这个时候机器 B 会受到两个数据包,那么机器 B 是如何分别这两个数据包是属于同一份数据还是不同的数据?
这就须要后面讲过的办法:给数据字节进行编号。这样接管方就能够依据数据的字节编号,得出这些数据是接下来的数据,还是重传的数据。
在 TCP 首部有两个字段:序号和确认号,他们示意发送方数据第一个字节的编号,和接管方期待的下一份数据的第一个字节的编号。
间断 ARQ 协定
进行期待协定曾经能够满足牢靠传输了,但有一个致命毛病:效率太低。发送方发送一个数据包之后便进入期待,这个期间并没有干任何事,节约了资源。解决的办法是:间断发送数据包。模型如下:
和进行期待最大的不同就是,他会源源不断地发送,接管方源源不断收到数据之后,逐个进行确认回复。这样便极大地提高了效率。但同样,带来了一些额定的问题:
发送是否能够有限发送直到把缓冲区所有数据发送完?不能够。因为须要思考接管方缓冲区以及读取数据的能力。如果发送太快导致接管方无奈承受,那么只是会频繁进行重传,节约了网络资源。所以发送方发送数据的范畴,须要思考到接管方缓冲区的状况。这就是 TCP 的流量管制。
解决办法是:滑动窗口。根本模型如下:
- 发送方须要依据接管方的缓冲区大小,设置本人的可发送窗口大小,处于窗口内的数据表示可发送,之外的数据不可发送。
- 当窗口内的数据接管到确认回复时,整个窗口会往前挪动,直到发送实现所有的数据
在 TCP 的首部有一个窗口大小字段,他示意接管方的残余缓冲区大小,让发送方能够调整本人的发送窗口大小。通过滑动窗口,就能够实现 TCP 的流量管制,不至于发送太快,导致太多的数据失落。
间断 ARQ 带来的第二个问题是:网络中充斥着和发送数据包一样数据量的确认回复报文,因为每一个发送数据包,必须得有一个确认回复。进步网络效率的办法是:累积确认。
接管方不须要一一进行回复,而是累积到一定量的数据包之后,通知发送方,在此数据包之前的数据全都收到。例如,收到 1234,接管方只须要通知发送方我收到 4 了,那么发送方就晓得 1234 都收到了。
第三个问题是:如何解决丢包状况。在进行期待协定中很简略,间接一个超时重传就解决了。但,间断 ARQ 中不太一样。
例如:接管方收到了 123 567,六个字节,编号为 4 的字节失落了。依照累积确认的思路,只能发送 3 的确认回复,567 都必须丢掉,因为发送方会进行重传。这就是 GBN(go-back-n) 思路。
然而咱们会发现,只须要重传 4 即可,这样不是很浪费资源,所以就有了:抉择确认 SACK。在 TCP 报文的选项字段,能够设置曾经收到的报文段,每一个报文段须要两个边界来进行确定。这样发送方,就能够依据这个选项字段只重传失落的数据了。
牢靠传输小结
到这里对于 TCP 的牢靠传输原理就曾经介绍得差不多。最初进行一个小结:
- 通过间断 ARQ 协定与发送 - 确认回复模式来保障每一个数据包都达到接管方
- 通过给字节编号的办法,来标记每一个数据是属于重传还是新的数据
- 通过超时重传的形式,来解决数据包在网络中失落的问题
- 通过滑动窗口来实现流量管制
- 通过累积确认 + 抉择确认的办法来进步确认回复与重传的效率
当然,这只是牢靠传输的冰山一角,感兴趣能够再深刻去钻研。
起源:https://www.toutiao.com/i6954…