网络技术 百分网手机站

程序员应该了解的网络协议

时间:2020-09-16 12:52:33 网络技术 我要投稿

程序员应该了解的网络协议

  引导语:网络协议是进行网络连通信的重点,以下是小编整理的程序员应该了解的网络协议,欢迎参考阅读!

程序员应该了解的网络协议

  网络路由

  在过去的模拟电话中,拨打电话意味着从电话到朋友那里具有真实的电线连接。就好像电线直接从你那里连接到他们那里。虽然没有这样实际的电线,当然——连接是通过复杂的开关系统进行的——但它与电线相当。

  有太多的Internet节点可以这样工作。但是我们不能从每个机器到要和其对话的其他机器提供直接、不间断的路径连接。

  相反,数据是桶式的,从一个路由器传递到下一个路由器,在链路中,每个路由器使数据更靠近目的地。 我的笔记本电脑和谷歌服务器之间的每个路由器连接到其他多个路由器,这样维护着一个粗略的路由表,显示哪些路由器更接近互联网的哪个部分。当一个数据包到达的目的地是谷歌服务器时,路由表中的快速查找功能告诉数据包走哪个路由器能够更加靠近谷歌服务器。数据包很小,所以链路中的每个路由器只会对下一个路由器占用一小段时间。

  路由解决的问题可分为两个子问题。首先,解决:数据的目的地是什么?这由IP、互联网协议、IP地址处理。IPv4仍然是IP的最常见版本,仅提供32位地址空间。现在已完全分配,因此将一个节点添加到公共Internet需要重用现有的IP地址。 IPv6允许2128个地址(约1038个),但截至2017年只有约20%被使用。

  现在我们有地址,我们需要知道如何通过互联网将数据包路由到其目的地。路由过程发生得很快,所以没有时间查询远程数据库的路由信息。例如,Cisco ASR 9922路由器的最大容量为每秒160兆比特。假设完整的1500字节数据包(12,000位),也即是在一个19英寸机架中每秒13333333333个数据包!

  为了快速路由,路由器维护路由表,指示各种IP地址组的路径。当新数据包到达时,路由器在表中查找它,告诉它哪个对等体最接近目的地。它将数据包发送给该对等体并移动到下一个。BGP的工作是在不同路由器之间传递此路由表信息,确保是最新的路由表。

  不幸的是,IP和BGP一起并不能搭建有效的网络,因为它们没有办法可靠地传输数据。如果路由器过载并丢包,我们需要一种方法来检测丢失并请求重传。

  分组交换

  如果互联网通过路由器将网络中彼此之间的数据相互连接起来,那么当数据量大时会发生什么? 如果我们请求88.5 MB的JavaScript Birth & Death视频,应该怎么办?

  我们可以尝试设计一个网络,其中88.5 MB文档从Web服务器发送到第一个路由器,然后到第二个,以此类推。不幸的是,该网络在互联网规模上甚至内部网络规模都无法工作。

  首先,计算机是具有有限存储量的有限个机器。如果一个给定的路由器只有88.4 MB的缓冲区可用,它根本不能存储88.5 MB的视频文件。因此数据将被丢弃,更糟糕的是,这没有任何迹象。如果路由器十分繁忙而丢失数据,那么无法花时间告诉我丢弃的数据。

  二是电脑不可靠。有时,路由节点失败。 有时,船舶的锚点会意外损坏关乎大量互联网数据的水下光纤电缆。

  由于这些原因,我们不会通过互联网发送88.5 MB的邮件。相反,我们将它们分解成数据包,通常在每个1,400字节左右。我们的视频文件将分为63,214个单独的数据包进行传输。

  无序数据包

  通过数据包捕获工具Wireshark测量JavaScript的Birth & Death实际传输情况,我收到的总共接收到61,807个数据包,每个是1,432个字节。将这两个相乘,我们得到88.5兆字节数据,这是视频的大小。(这不包括各种协议增加的开销,如果包括,我们会看到稍高一些的数据大小)

  传输是通过HTTP完成的,一种通过TCP分层的协议,即传输控制协议。它只需要14秒,因此数据包的平均速率约为每秒4,400,或每包约250微秒。在14秒钟内,我的机器收到全部的61,807个数据包,可能是无序的,当它们进来时将它们重新组装成完整的文件。

  使用最简单的机制重新组装TCP包,可以想象:一个计数器。每个数据包发送时都会分配一个序列号。在接收端,按照序列号对数据包进行排序。一旦这一切都顺利,没有差别,我们知道文件是完整的。(实际的TCP序列号往往不是整数,每次只增加1,但这个细节在这里并不重要。)

  我们怎么知道文件何时完成?TCP并不能回答,因为这是更高级协议的工作。例如,HTTP会有包含一个“Content-Length”头,指定响应长度(以字节为单位)。客户端读取Content-Length,然后继续读取TCP数据包,将其组装成原始顺序,直到它具有Content-Length指定的长度。这就是HTTP头(和大多数其他协议头)先于响应有效负载到来的一个原因:否则,我们不知道有效负载的大小。

  当我们在这里说“客户”时,我们实际上在谈论整个电脑接收端。TCP重组发生在内核内部,因此Web浏览器和curl和wget等应用程序不必手动重新组合TCP数据包。但内核不处理HTTP,因此应用程序必须了解Content-Length头文件,并知道要读取的字节数。

  使用序列号和分组重新排序,即使数据包无序到达,我们也可以发送大的字节序列。但是如果一个数据包在传输中丢失了,会在HTTP响应中留下一个空白吗?

  传输窗口和慢启动

  我们一边开着Wireshark,一边下载“Death and Death of JavaScript”。通过浏览捕获的结果,我们看到源源不断的数据包被接收到。

  例如,序列号为563,321的数据包到达。像所有TCP数据包一样,它有一个“下一个序列号”,它是用于下一个数据包的数字。该数据包的“下一个序列号”为564,753。事实上,下一个数据包的序列号也的确为564,753,所以一切都很好。当连接达到一定速度后,每秒钟会发生数千次传输。

  有时候,我的电脑会向服务器发送一条消息,例如“我已收到所有数据包,包括数据包564,753”。这是一个ACK,用于确认:我的电脑确认收到服务器的数据包。在一个新的连接上,Linux内核每十个数据包发送一个ACK。这由TCP_INIT_CWND常量控制,我们可以在Linux内核的源代码中定义它们。(TCP_INIT_CWND中的CWND表示拥塞窗口:一次允许的数据量)如果网络拥塞(超载),窗口大小将减少,传输数据包变慢)。

  十个数据包大约是14 KB,所以我们一次限制在14 KB数据。这是TCP慢启动的一部分:连接从小拥塞窗口开始。如果没有数据包丢失,接收机将不断增加拥塞窗口,允许一次传输更多的数据包。

  有时,数据包将发生丢失,所以接收窗口会缩小,传输速度变慢。通过自动调整拥塞窗口以及一些其他参数,发送方和接收方保持数据移动速度在网络允许的情况下尽可能快,但不会超出限制。

  这种情况发生在连接的两端:每一方都会确认对方的消息,并且每一方都保留自己的拥塞窗口。非对称窗口允许协议充分利用具有不对称上行和下行带宽的网络连接,比如大多数住宅和移动互联网连接。

  可靠传输

  电脑不可靠:由计算机组成的网络是不可靠的。在像因特网这样的大型网络中,故障是运行的正常部分,必须适应。在分组网络中,这意味着重传:如果客户端接收到数据包1和3,但没有接收到2,则需要请求服务器重新发送丢失的数据包。

  当每秒接收数千个数据包时,如我们的88.5 MB视频下载,错误几乎是必然的。为了证明,让我们回到我的Wireshark捕获的下载。对于数千个数据包,一切正常。每个数据包指定一个“下一个序列号”,后面是另一个包含该数字的数据包。

  突然间出了问题。第6,269个数据包具有7,208,745的“下一个序列号”,但该数据包一直没有到来。相反,序列号为7,211,609的数据包到达。这是一个乱序的数据包:意味着缺少一些东西。

  我们不清楚这里出了什么问题,也许互联网上的一个中间路由器过载,也许我的本地路由器超载,也许有人使用微波炉,引入电磁干扰并减慢了我的无线连接。在任何情况下,数据包丢失,唯一的指示是接收到意外的数据包。

  TCP没有特殊的“我丢了一个包!”信息。相反,ACK被巧妙地用于指示丢失。当出现乱序的数据包时,接收机会re-ACK最后一个好的'数据包——即正确顺序的最后一个数据包。实际上,接收机正在说“我收到了我正在确认的数据包5,之后也收到了一些信息,但是我知道它不是数据包6,因为它与数据包5中的下一个序列号不匹配。

  如果两个数据包在传输过程中被交换了顺序,则会导致单个额外的ACK,并且在收到无序数据包后,所有内容都将继续正常传输。但是如果数据包真的丢失,意外的数据包将继续到达,并且接收器将继续发送最后一个好数据包的ACK副本。这可能导致数百个重复的ACK。

  当发送方在一行中看到三个重复的ACK时,它假定下一个数据包丢失并重发。这被称为TCP快速重传,因为它比以前基于超时的方法更快。有趣的是,协议本身没有任何明确的方式说“请立即重发!”相反,协议产生的多个ACK自然用作了触发器。(一个有趣的思考实验:如果一些重复的ACK丢失,从未到达发送者,会发生什么?)

  即使网络正常工作,重传也是很常见的。在我们的88.5 MB视频下载中,我看到了这一点:

  由于持续成功的传输,拥塞窗口迅速增加到大约一兆字节;

  1)有几千个包顺序出现,一切正常;

  2)一个数据包发生故障;

  3)数据继续以兆字节/秒计算,但数据包仍然丢失;

  4)我的机器发送最后一个已知好数据包的数十个重复的ACK,但是内核还存储待处理的无序数据包以供稍后重新组装;

  5)服务器接收重复的ACK并重新发送丢失的数据包;

  6)我的客户端对以前丢失的数据包和随后由于无序传输已经收到的数据包进行ACK。这是通过简单地确认最近的数据包来完成的,这个数据包也隐含地对所有较早的数据进行ACK。

  7)传输继续,但是由于丢失的数据包,拥塞窗口缩小。

  这个是正常的,这是发生在我所完成的完整下载的每个捕获中。尽管我们认为日常生活中网络是不可靠的,甚至TCP在正常条件下也会偶尔失败,但是TCP仍然是工作得很出色的。

  物理网络

  所有这些网络数据必须通过物理介质(如铜缆,光纤和无线电)传输。在物理层协议中,以太网是最为人所知的。在互联网的早期,它的受欢迎程度使我们设计其他协议以适应其限制。

  首先,让我们认识物理细节。以太网与RJ45连接器关系最为紧密,RJ45连接器看起来像更大的八针版本的老式四针手机插孔。它还与cat5(或cat5e或cat6或cat7)电缆相关联,其中包含绞合成四对的八根总线。这里还存在其他媒体,如我们最有可能在家中遇到的:八根电线缠绕在与8针插孔相连的护套中。

  以太网是物理层协议:它描述了这些位如何变成电缆中的电信号。它也是一个链路层协议:它描述了一个节点与另一个节点的直接连接。但是,它纯粹是点对点的,并且与数据在网络上的路由无关。在这一层没有TCP概念中的链接概念,也没有IP地址意义上的可重新分配地址的概念。

  作为协议,以太网有两个主要的工作。首先,每个设备需要注意它连接的设备,需要协商一些连接速度等参数。

  第二,一旦链路建立,以太网需要携带数据。像较高级协议如TCP和IP一样,以太网数据被分解成数据包。数据包的核心是一个帧,它有一个1500字节的有效载荷,再加上另外22个字节的头信息,如源和目标MAC地址,有效载荷长度和校验和。经常处理地址长度与校验和的程序员对这些领域是很熟悉的,我们可以想象为什么它们是必要的。

  然后将帧包含在另一层的header中以形成完整数据包,但这些header很奇怪。他们开始与模拟电气系统的基础现实相反,所以他们看起来似乎不会被放在软件协议中。完整的以太网数据包包含:

  1)前导码是56位(7字节)的交替1和0。设备使用它来同步他们的时钟,就像当人们计数“1-2-3-GO!”时一样。计算机无法计数超过1,所以他们通过说“101010101010101010101010101010101010101010101010101010”进行同步。

  2)8位(1字节)起始帧分隔符,为171(10101011为二进制),这标志着前导码的结束。请注意,再次重复“10”,直到“11”为止。

  3)如上所述,帧本身包含源和目的地址,有效载荷等。

  4)96位(12字节)的间隔间隙,其中line处于空闲状态。大概这是让设备休息,因为它们很累。

  把这一切放在一起:我们想要的是传输我们的1500字节的数据。我们添加22个字节来创建一个帧,它指示源,目标,大小和校验和。我们再添加20个字节的额外数据来满足硬件需求,创建完整的以太网数据包。

  你可能认为这就是堆栈的底层。并不是这样,反而因为模拟世界变得越来越复杂,堆栈底层也变得越来越复杂。

  当网络遇见现实世界

  数字系统不是真实存在的;所有一切都是模拟的。

  假设我们有一个5伏CMOS系统。(CMOS是一种数字系统,如果你不熟悉也不用担心)这意味着一个完全开启的信号将是5伏,一个完全关闭的信号将是0。但没有什么是永远完全关闭或完全关闭的,因为物理世界不允许。实际上,我们的5伏CMOS系统将会考虑将高于1.67伏的任何值记为1,而低于1.67的任何值都将为0。(1.67是5的1/3,我们不用担心为什么阈值是1/3,如果你想深入研究,维基百科有一篇相关文章!而且,以太网不是CMOS甚至不与CMOS相关,CMOS和其1/3的值仅用于简单的说明。)

  我们的以太网数据包必须通过物理线路,这意味着更改电线上的电压。以太网是一个5伏系统,所以我们期望以太网协议中的每1位为5伏,每个0位为0伏。但是有两个窍门:首先,电压范围是-2.5 V到+2.5 V。其次,更奇妙的是,每组8位在到达电线之前就会扩展成10位。

  有256个可能的8位值和1024个可能的10位值,因此可以将其映射到表中。每个8位字节可以映射到四个不同的10位模式中的任一个,每个模式将被转回到接收端的同一个8位字节。例如,10位值00.0000.0000可能映射到8位值0000.0000。但也可能10位的值10.1010.1010也映射到0000.0000。当以太网设备看到00.0000.0000或10.1010.1010时,它们将被理解为字节0(二进制0000.0000)。(警告:现在有一些电子相关的术语。)

  这是为了提供特别的模拟电路需求:平衡设备中的电压。假设这个8位到10位编码不存在,我们发送一些恰好全是1的数据。以太网的电压范围为-2.5至+2.5伏,因此我们将以太网电缆的电压保持在+2.5 V,不断从另一侧拉电子。

  为什么我们关心一方比另一方更多的电子?因为模拟世界是混乱的,会造成各种不良影响。要采取一个:它可以对低通滤波器中使用的电容器进行充电,从而在信号电平本身产生偏移,最终导致位错误。这些错误将需要时间来积累,但是我们不希望我们的网络设备在两年的正常运行时间之后突然破坏数据,就因为我们碰巧发送了1比0多的二进制数。(电子相关术语在这里结束。)

  通过使用8b / 10b编码,以太网可以平衡通过线路发送的0和1数量,即使我们发送大多数为1或大多数为0的数据。硬件跟踪0到1的比例,将溢出的8位字节映射到10位表的不同选项,以实现电气平衡。(较新的以太网标准,如10 GB以太网,使用不同的和更复杂的编码系统。)

  我们就讨论到这里,因为我们已经超出了可以被视为编程的范围,但是还有更多的协议来适应物理层。在许多情况下,硬件问题的解决方案在于软件本身,如在用于校正DC偏移的8b / 10b编码的情况下。这对程序员来说可能有点令人不安:我们喜欢假装我们的软件生活在一个完美的柏拉图式世界,没有粗俗的物理缺陷。实际上,一切都是模拟的,并且限制着每个人的工作和软件的复杂性。

  互联网络栈

  互联网协议最好被理解为层堆栈。以太网提供物理数据传输和两个点对点设备之间的链接。IP提供了寻址层,允许路由器和大型网络存在,但它是无连接的。分组数据被发射到以太网中,但没有指示是否到达的功能。TCP通过使用序列号,通过确认和重传来添加一层可靠的传输。

  最后,像HTTP这样的应用层协议在TCP之上。在这个层面上,我们能够寻址,并且似乎实现了可靠传输和持续连接。IP和TCP将应用程序开发人员从不断重新实现数据包重传和寻址等工作中解放出来。

  这些层的独立性很重要。例如,当我的88.5 MB视频传输丢包时,互联网的骨干路由器不知道,只有我的机器和网络服务器知道。来自我计算机的数十个重复ACK都被完全路由在丢失原始数据包的相同路由基础设施上。负责丢弃丢包路由器的也可能是几毫秒后更换的路由器。这是理解互联网的重要一点:路由基础架构并不了解TCP,它只有路线。(虽然有一些例外,但通常是这样的。)

  协议栈的层独立运行,但它们不是独立设计的。更高级别的协议往往建立在较低级别的协议上:HTTP建立在基于IP的TCP上,IP建立在以太网上。较低层次的设计决策往往影响更高层次的决策,甚至影响数十年后的决策。

  以太网是传统的,涉及到物理层,所以它需要设置基本参数。以太网有效载荷最多为1500字节。

  IP包需要配置在以太网帧中。IP具有20字节的最小报头,因此IP数据包的最大有效负载为1,500 - 20 = 1,480字节。

  同样,TCP分组需要适应IP分组。TCP也具有20字节的最小报头,最大TCP有效负载为1,480 - 20 = 1,460字节。实际上,其他header和协议可以进一步减少。1,400是一个保守的TCP有效载荷大小。

  1,400字节的限制影响现代协议的设计。例如,HTTP请求通常很小,如果我们将它们分配于一个数据包而不是两个数据包,那么我们可以减少丢失部分请求的可能性,同时可以减少TCP重传的可能性。为了从HTTP请求中挤出字节,HTTP / 2指定了头文件的压缩,这通常很小。没有来自TCP,IP和以太网的上下文,这似乎很愚蠢:为什么添加到协议的header压缩来只保存几个字节?因为按照HTTP / 2规范在第2节的介绍,压缩允许“许多请求被压缩成一个数据包”。

  HTTP / 2的header压缩是为了满足来自IP约束的TCP限制,这些限制来自于20世纪70年代开发的以太网中的约束,1980年开始实施,并于1983年进行了标准化。

  最后一个问题:为什么以太网有效载荷大小设置为1500字节?没有深刻的理由,这只是一个很好的折衷点。每帧需要42字节的非有效载荷数据。如果有效载荷最大值只有100字节,那么只有70%(100/142)的时间用于发送有效载荷。有效载荷为1500字节意味着大约有97%(1500/1542)的时间用于发送有效载荷,这是一个很好的效率水平。将数据包大小提高较多的话,则设备需要较大的缓冲区,我们还是很难获得另外高1%或2%的效率。简而言之:HTTP / 2的header压缩是由于20世纪70年代后期网络设备的RAM限制而导致的。

【程序员应该了解的网络协议】相关文章:

网络不通应该如何检查10-06

应该如何做明确目标java程序员职业规划11-22

网络直播应该保护未成年人权益11-15

TCP/IP网络协议知识点的归纳09-24

替代HTTP的分布式网络协议介绍09-22

报检员的工资待遇了解10-13

了解科目四的考试流程11-30

高考政策信息了解11-15

深入了解Java中的接口11-23