前言
对于计算机网络方面的内容,我比拟苦恼,该如何组织内容,将这部分内容如何和本人对网络编程的认知联合起来,还有就是介绍程序,引论之后是依照大学教材的程序,还是跳过物理层(这一层离程序员的确有点远,所以这部分内容不思考介绍),数据链路层、网络层,应用层,还是自顶向下,应用层、传输层、网络层、数据链路层。这其实也是在取舍,因为我大学上这门课的时候,教材的程序是自下往顶,而后我听了大略几个星期之后,齐全抉择放弃,因为听不懂,我感觉这些货色摸不到,我失去的只是一些形象的概念,落不了地,也可能跟过后没有做过网络开发的工作相干,在毕业之后实习,写了一点网络编程的代码,才缓缓了解起大学教材的概念,所以这也是这个系列会交叉一点网络编程框架介绍的起因。明天在应用层、网络层、传输层,这三层斟酌了颇长时间,最终还是决定先写 TCP 相干的内容。
咱们回顾一下在《计算机网络引论》外面的内容,看似简略而又日常的网络通信,其实是一个简单的问题,为了升高问题的复杂度,计算机网络的先驱们,采取了分层的策略来解决通信过程中所遇到的问题,国际化规范组织于 1977 年成立了专门的组织来钻研该问题,该组织提出的分层计划是将网络分为七层,因为该模型比拟理想化,最终没被市场所采纳,最终风行的是 TCP/IP 协定的四层规范,在学习计算机网络原理的时候往往采取折中的计划,将网络分为五层。
五层协定的体系结构只是为介绍网络原理,理论利用还是 TCP/IP 协定的四层体系结构。咱们自顶向上再来大抵的介绍一下各层的职能划分,加深记忆。
- 物理层: 规定电气个性,多大的电压代表“1”或“0”等
-
数据链路层: 两台计算机之间的数据传输总是在一段一点的链路上传送的,这就须要专门的链路层的协定。在两个相邻结点之间传送数据时,数据链路层
将网络层交下来的数据包组装成帧,每一帧包含数据和必要的管制信息(如同步信息、地址信息、差错控制等)。
这样说可能有点形象,咱们来讲一个小故事来领会一下:
杨贵妃喜爱吃香蕉,皇帝为了让爱妃吃的开心,皇帝命令大臣日夜兼程将香蕉从海南运输到长安。
那么香蕉从海南到长安总共须要几步:
第一步: 首先须要用船将香蕉运出岛,运到广东的码头。
第二步: 从广东运向长安,这个时候还没有飞机,所以两头会坐船,骑马,换乘交通工具。
第三步: 香蕉达到目的地。
如果将士兵比喻成 IP 包,则马、船只就是数据链路层,这也就是 IP 包每一跳须要更换数据链路层,就如同士兵须要一直变换交通工具一样天然,局势所迫。
那为什么士兵会抉择将香蕉运到广东,从广东再运到长安,而不是运到非洲再运到长安呢,因为你广东离长安更近啊。
那为什么士兵不间接奔向长安?而是先到广东码头,因为码头是必经之地,码头是通向目的地长安的一块跳板,只管不是最终目的地,但士兵 (IP 包) 却须要通过它。
如果有飞机呢,士兵是不是能够直飞长安呢,在这里飞机同样是数据链路层,因为它的目标是服务士兵(IP) 包,而士兵最终的目的地:长安。
- 网络层:
在《计算机网络引论》中,咱们讲到 IP 层还有一个相似于理论住址的性能,便于动静路由,mac 地址像是身份证,而 IP 层的 IP 则像是理论住址一样。
但其实这个必须还是有不失当的中央,这事实上把一部分传输层的性能也划入了网络层,mac 地址更像是房间的地址,房子一旦建成,经度纬度不会再发生变化了。快递达到理论寓居房间之后,外面有好多人,那怎么确定这个快递是谁的呢,这就是传输层的工作之一。
- 传输层
有了 IP、MAC 地址,还是无奈确定这个数据包要给哪个过程,运输层提出了端口的概念,通过 IP+ 端口即可确定这个数据包能够给谁,相似于快递到房间之后,会叫名字,因为名字不是惟一的,快递员还会复核一下手机号。但快递的货色失落了怎么办,让卖家再发一次喽,尽管在运输过程中都是在尽最大致力交付,然而在运输过程中还是可能产生丢数据包的景象,个别的买家会让卖家再重发,这样的买家和卖家是 TCP 协定,但有的买卖双方是丢了也不给你重发,也就是 UDP 协定。
- 应用层
有了快马加鞭运输系统,皇帝小孩儿个别是不怎么放心运输问题的,有的时候皇帝会发旨意,有的时候会发赏赐,这也就是利用过程之间的交互。
TCP 概述
连贯治理
TCP 是 TCP/IP 体系中非常复杂的一个协定,TCP 是面向连贯的运输层协定,这就是说应用程序在应用 TCP 协定之前,必须先建设 TCP 连贯,在数据开释完之后,必须开释曾经建设的 TCP 连贯。其实在学到这个 TCP 连贯的时候,我对这个连贯多多少少是感觉了解不透的,我将其了解为通信之前确认通信单方的状态,打电话的时候有个拨号的过程,然而对面挂断电话的话,这个打电话界面也就退出了,这个我是了解的,然而这个连贯我就了解不到实体上,哪个是电话,拨号过程在哪里?再有,我如何去应用 TCP 协定,TCP 协定是蛮简单的一个协定,我要编写通信软件不会还要我本人去实现一把这个协定吧。
当然不会让程序员用高级语言再实现一把 TCP 协定,这是一个宏大而又简单的工程,TCP/IIP 协定曾经驻留在操作系统中,因为 TCP/IP 协定被设计成能运行在多种操作系统的环境中,因而 TCP/IP 协定规范没有规定应用程序与 TCP/IP 协定如何接口 (调用) 的细节,而是容许零碎设计者可能抉择无关 API 的具体实现细节。
目前来说只有几种可供应用程序应用的 TCP/IP 的利用程序接口,最驰名的就是美国加利福利亚大学伯克利分校为 Berkeley UNIX 操作系统定义的 API,被称为套接字接口(socket interface)。微软在其操作系统中采纳了套接字 API,然而有一点不同,咱们称之为 Windows Socket。AT&T 的 Unix System V 版本定义的接口,简写为 TLI(Transport Layer port)
因为有不同的实现,所以在不同的操作系统上行为可能会有点差别,也就是在 TCP/IP 协定上做独自的定制,但最终都实现了 TCP/IP 协定,次要的行为不会有差别。
操作系统对外部裸露运输层和应用层通信的接口,个别咱们称之为 Socket API。个别高级语言都留有调用操作系统 Socket API 的实现。咱们用 Java 来演示一下调用操作系统提供的运输层 TCP 协定:
public class SocketClient{public static void main(String[] args) throws Exception {
// 这行代码会尝试和我本地端口为 12345 建设连贯
// 如果始终追着看会发现, 最终调的是一个 native 办法
// 最终还是调的操作系统的办法
// 由操作系统返回是否可能建设连贯、连贯状态
Socket socket = new Socket("127.0.0.1",12345);
}
}
这就相似于打电话了,通信之前,确认信道的品质。少数与 TCP 相干的文章都会从三次握手和四次握手登程,这里我试图先大抵描绘出 TCP 的主体,再别离去介绍 TCP 的各个局部。连贯治理也是 TCP 协定中的一个重要局部。
牢靠传输概述
TCP 协定提供牢靠交付服务,通过 TCP 连贯传输的数据,无差错、不失落、不反复,并且按序达到。咱们称之为牢靠传输,为了实现可靠性传输,须要思考很多事件,例如数据的毁坏、丢包、反复以及分片程序凌乱等问题。如果不能解决这些问题,也就无从谈起牢靠传输。
咱们先大抵先从最简略的进行期待协定动手,看看为了实现牢靠传输要做哪些事件,真正的 TCP 应用的牢靠传输协定要远比这个进行期待协定要简单的多。
全双工通信的单方既是否发送方也是接管方,为了探讨问题不便,咱们仅思考 A 发送数据 B 接收数据并发送确认。因而 A 叫做发送方,而 B 叫做接管方,将传送的数据单元都称为分组。进行期待协定中的进行期待就是每发送一个分组就进行发送,期待对方的确认,在收到确认之后,再发送下一个分组。
进行期待协定能够用下图来阐明:
下面是一种十分现实的通信状况,A 发送分组 M1,发完就暂停发送,期待 B 的确认。B 收到了 M1 就向 A 发送确认,A 收到了对 M1 的确认,就发送下一个分组 M2。
同样,在收到 B 对 M2 的确认之后,再发送 M3. 然而如果说在传输过程中呈现了过错呢,B 在接管到 M1 时对 M1 进行检测,发现 M1 缺失,就抛弃 M1 这个报文,当然也可能 B 压根就没收到 M1,在这种状况下,B 都会向 A 发送任何音讯。牢靠传输协定个别是这么设计的: A 只有超过一段时间依然没有收到确认,就认为方才发送的分组失落了,因此重传后面发过的分组,这叫超时重传。要实现超时重传,就要在每发送一个分组时,设置一个超时计时器。如果在超时计时器到期之前收到了对方的告诉,就撤销设置的超时计时器。
这里应该留神以下三点:
- A 在发送一个分组后,必须临时保留已发送的分组的正本(在发送超时重传时进行应用),只有在收到相应的确认之后能力临时革除临时保留的分组正本。
- 分组和确认分组都必须进行编号,这样能力明确是哪一个发送进来的分组收到了确认,而哪一个分组还没有收到确认。
- 超时工夫的设置,重传工夫该当比在分组传输的均匀往返工夫要更长一些,不能太长,通信效率就会很低,太短就会产生很多不必要的重传。
在传输信息的过程中还有两种状况值得咱们留神:
- 确认失落
下面的出错状况是出在发送方发给接管方的过程,这种状况是接管方在传输给发送方刚确认的时候产生,A 在指定的工夫内没有收到 M1 确认,也没有方法确认是本人发的分组出错、还是失落,或者 B 发送的确认失落了。因而 A 在超时器到期之后就会再传输一次 M1。
对于 B 来说此时就应该采取两个动作:
- 抛弃这个反复的分组 M1,不向下层交付
- 向 A 发送确认。不能认为曾经发送过确认就不再发送,因为 A 之所以重传 M1 就阐明 A 没有收到确认。
-
确认早退
B 发送给 A 对 M1 的确认早退了,但 B 会再发一次,在这种状况下 A 会收到反复的确认,对反复的确认解决很简略: 收下后就抛弃。B 依然会收到反复的 M1,并且重传确认分组。
通常状况下 A 最终总是能够收到对所有收回分组的确认,如果 A 一直重传分组然而总是收不到确认,那就是阐明通信线路太差,不能进行通信。应用上述确认和重传机制,咱们就能够在不牢靠的传输网络上实现牢靠的通信。
TCP 并未采纳进行期待协定,因为信道的利用率太低了,咱们会在前面的文章,做具体的介绍。
流量管制
一般来说,咱们总是心愿数据传输得更快一些,但如果发送方把数据发送得过快,接管方就可能接管不迭,写到这里我忽然想起了打球,脑子里呈现的场景是,两个人干活,一个人将运输物品给另一人,咱们将其命名为 A 和 B,刚开始是 A 一个一个的发送, A 如果加大速度,这个物品 B 接管不迭,就可能掉在地上。为了防止这种状况,TCP 引入了流量管制,所谓流量管制就是让发送方的发送频率不要太快,要让接管方来得及接管。
拥塞管制
过年来回上海,我问司机徒弟什么时候能到我住的中央,司机说当初下班的人没回来,开的快。事实上在网络中也会有这样的状况,一般来说计算机网络都处在一个共享的环境,如果说某时刻发送音讯的比拟多,就像是马路上有很多车,这种状况咱们称之为网络拥挤,如果持续发送大量数据包,就可能会导致数据包延时、失落等,这时 TCP 就会重传数据,然而一旦从重传救护导致网络的累赘更重,于是乎导致更大的提早以及更多的丢包,这就会进入恶性循环一直地放大。
所以 TCP 不能疏忽网络上产生的事,它被设计成一个自私的协定,当网络发送拥塞时,TCP 会升高发送的数据量。于是就有了拥塞管制,管制的目标就是防止发送方的数据填满整个网络。
写在最初
本位大抵介绍了传输层协定要解决的问题,以及传输层的一个重要协定 TCP 协定的大抵组成,心愿能从宏观上对 TCP 协定有一个大抵的意识,没有抉择从高频面试题三次握手登程介绍,先整体再部分,这样能够让咱们有一条主线,不至于迷失在细节中。这个系列的文章也有实习面试的缘故,我记得还是蛮分明的,过后面试官出题,我答的不好,前面其实打算重学一下,算是再回应。其实实习的时候有很多让我印象很深的问题,大抵都通过这些年的学习找到了答案,目前还差一个编译原理相干的系列还没开始,这算是旧坑未填完,又挖新坑了。
参考资料
- 能不能艰深讲一讲数据链路层到底有什么用?知乎答主 https://www.zhihu.com/questio…
- 30 张图解:TCP 重传、滑动窗口、流量管制、拥塞管制发愁 https://zhuanlan.zhihu.com/p/…
- 《深刻了解计算机系统》第三版
- tcp 的伯克利实现与当今的 tcp 实现差距有多大?https://www.zhihu.com/questio…