前言

我大学是学网络工程专业,也就是那种拉网线,面向网线编程的。依稀记得学习计算机网络这门课程的时候搭建的IT宅 itzhai.com个人网站。

算一下,学这门课程也已经快十年了。

某一天,偶然又看到了这本书:

image-20200726213509847

翻了下,发现里面的内容竟然还是毫不过时,真的是越底层的知识越有价值呀。我擦了擦书面的灰尘,决定要为它写点什么,于是又从书架上找了相关的书籍:

image-20200726211636509

来回翻阅和梳理总结,逐渐输出了这篇文章,献给对网络不太熟悉,又想快速从入门到熟练的朋友们。

相信大家拿到Socket API,就可以很快写好代码,收发消息,传送文件什么的,可是底层究竟发生了什么?TCP、UDP、HTTP是什么关系、为啥要有WebSocket编程。我们从TCP/IP协议栈以及一根网线说起,逐步揭开面向网线编程内功心法的面纱。

最后,在这里解答一个问题:有人问我为什么要写公众号技术文章呢?工作越久,发现身边比自己年纪小的人越多,我也时常在想,那些同龄人或者比我大的人都去哪里了,也许有些人忙于家庭生活不亦乐乎,有些人因为公司上市拿到可观的收入转行了,也许有人在大公司做起了管理工作,开始走管理路线,带领团队创造新的产品。我写公众号的原因之一,也就是想告诉大家,我一直在做技术,一个坚持写代码的大龄技术人,并且希望能够结实更多志同道合的技术人。没错,在说你们呢,不要求三连,这篇文章对你感兴趣就点个在看呗。Thanks♪(・ω・)ノ

本文的各种电脑、服务器、路由器小图标都是我一笔一笔画的用心只做了尽量美观有趣好理解的配图,旨在希望能够有助于大家理解文章内容,真心希望产品经理也可以看懂。

1、网络分层

1.1、OSI七层模型

为了制定一个统一的计算机网络体系,国际标准化组织ISO提出了一个试图使各种计算机可以在世界范围内互联成网的标准框架:OSI/RM(Open System Interconnection Reference Model 开放系统互连基本参考模型),该模型如下:

image-20200708085822940

媒介层:第一到第三层称为媒体层,它们主要与硬件相关,例如路由,交换和电缆规格;

主机层:第四到第七层称为主机层,它们是实现网络服务相关的软件。

大致介绍一下各层(注意:看看就好,这不是重点,重点是后面的TCP/IP协议):

  • 物理层:物理层负责在设备和物理传输介质直接传输和接收非结构化原始数据。这一层中,把数字位转换为电,无线电或光信号。可以发现这一层往往跟各种材质啊信号呀什么的打交道,所以称为物理层;
  • 数据链路层:在通过物理层连接的两个节点之间进行传输数据帧,检测并且纠正物理层中可能发生的错误。它定义了在两个物理连接的设备之间建立和终止连接的协议,还定义了他们之间的流控制协议;
  • 网络层:构建和管理多节点网络,包括寻址、路由、流量控制。网络层是一种可以连接许多节点的介质,每个节点都在其上有一个地址,通过目标地址就可以在节点之间传输数据到目标地址。网络层消息传输不一定要保证可靠,网络层系可以可以提供可靠的消息传递,但不必这样做;
  • 传输层:传输层提供了将可变长度数据序列从源传输到目标主机的功能和过程方法,同时又保持了服务功能的质量。一些协议是面向状态和面向连接的,这意味着传输层可以进行分段传输、支持失败重传;
  • 会话层:控制计算机之间的连接,负责建立、管理和终止本地和远程引用程序之间的连接,提供全双工、半双工或者单工操作;
  • 表示层:网络服务和应用程序之间的数据转换,如字符编码、数据压缩、加密解密;
  • 应用层:最接近最终用户的OSI层,该层直接与实现通信组件的软件应用程序进行交互。

可以发现,这个模型还真有点复杂。但很可惜,这个模型似乎不怎么流行,原因如下:

  • OSI专家缺乏实际经验,缺少商业驱动;
  • OSI协议实现过于复杂,运行效率低;
  • 标准制定周期长,市场已被其他标准占据;
  • 层次划分不太合理,部分功能在多个分层中出现。

在1980年代末和1990年代初的一段时间内,工程师、组织和国家对哪种标准(OSI模型或Internet协议套件)将更能塑造最佳和最强大的计算机网络存在争端,导致两极分化。尽管OSI在1980年代后期开发了其网络标准,后来更多的供应商网络上更多采用的却是TCP / IP标准,最终TCP/IP成为了实时的国际标准。

1.2、TCP/IP四层模型

下面我们把TCP/IP模型和OSI模型放一起对比下:

image-20200708234353206

可以发现,TCP/IP体系少了表示层和会话层,数据链路层和物理层用链路层取代。

  • 应用层:最高层,应用层的任务是通过应用进程间交互来实现特定网络应用。主要负责把应用程序中的用户数据传达给另一台主机或同一主机上的其他应用程序。这是所有应用程序协议的运行层,如SMTP、FTP、SSH、HTTP等;
  • 传输层:负责向两个主机中的进程之间的通信提供通用的数据传输服务。UDP是基本的传输层协议,提供了不可靠的无连接数据报传输服务;
  • 网络层:负责为分组交换网上的不同主机提供通信服务。该层定义了寻址和路由功能,主要协议是IP协议(Internet Protocol),它定义了IP地址,它在路由中的功能是将数据报传输到充当IP路由器的下一个主机,该主机更接近最终数据目的地;
  • 链路层:也称为数据链路层或者网络接口层,通常包括操作系统中设备驱动程序和计算机对应的网络接口卡。它们负责处理与传输媒介的物理接口细节。

而后面我们除了讲到各种协议之外,还会顺便提及一些底层硬件,为了更好的进行阐述,我们将把链路层再分为物理层和数据链路层,采用以下这种五层模型:

image-20200711112221679

根据运行模式分为以下两种:

  • 运行于用户进程:应用层,关注应用程序的细节,不关注底层网络通信细节;
  • 运行于内核:传输层、网络层、链路层,在内核中执行,主要处理所有的通信细节。

介绍了这么多概念,是不是比较难懂呢,没关系,我们列一下每一层主要的协议,接下来我们会详细的讲解各种协议的原理。

1.3、分层模型如何工作

这里我们通过一个FTP客户端的通信流程,来说明下两台主机是如何工作在TCP/IP分层模型上的:

image-20200711135012000

如上图,A主机的FTP客户端要与B主机的FTP服务器进行交互。

我们对设备做一下划分:

  • 端系统(End system):A主机和B主机
  • 中间系统(Intermediate system):路由器

其中用到的协议也做一下划分:

  • 端对端协议(End-to-end):包括应用层和传输层,端系统直接直接进行交互;
  • 逐跳(Hop-by-hop)协议:网络层,需要经过端系统中所有的中间系统。

对于应用层来说,他们好像是直接与端系统进行交互的,应用层根本不知道底层通信用了多少个路由器,是在以太网上还是在令牌环网上的。

什么是三层设备,二层设备?

如上图,路由器工作在网络层,属于第三层,所以经常有人称他为三层设备;而后面我们会讲到交换机,他是工作在第二层-数据链路层,所以也成为二层设备。

1.3.1、为什么要分层?

正如上面的例子,分层之后是的顶层屏蔽了底层的物理和通信细节。底层的通信原理是在较低的协议层中实现的,因此每个进程都将隐藏大多数通信细节。以此类推,在传输层,通信表现为主机到主机,而无需了解应用程序数据结构和连接的路由器。而在互联网络层,则在每个路由器上遍历各个网络边界。

就像我们搞软件开发划分层次一样,分层之后,提高了软件的复用度,封装每层细节,使用者只需要关注使用的API就可以了,不用关注实现细节。你不要告诉我你的一个功能涉及的一万行代码是写在一个函数里面的,那太可怕了。

想要了解底层细节的人,就只能拆开TCP/IP协议潘多拉之盒,逐个协议去了解了,这也是本文后边会继续探讨的内容。高度的封装,使得顶层开发人员能更快速的通过API开发应用程序。作为一个API工程师,你知道怎么调用API发送HTTP请求就够了,但是作为一个有追求的工程师,你了解了这些细节之后,就能够胜任程序调优以及更加底层的开发工作了。这也是为什么我坚持写IT宅 itzhai.com博客的原因:我想探索技术的本质,而不是生活在API构造的童话世界里面,这样即使童话世界谎言被拆穿的那天,也不至于失掉技术的信仰,因为我仍然有能力构建一个新的童话世界。

image-20200711120503245

接下来我们看看数据包从在传输过程中是如何封装的。

1.3.2、数据包的封装和分用

为了演示,我们需要构建一个局域网(LAN)。

假设我们现在直接通过两个网线把两台电脑连起来进行通信,需要做哪些工作呢。多亏我大学学的是网络工程,也是拉过网线的,所以多少还知道一点:

  • 准备一根网线,两个水晶头;
  • 水晶头要做交叉线,采用1-3,2-6交叉接法,保证两个水晶头之间能够正常收发信号;
  • 把两个水晶头分别插在两台主机的电脑上;
  • 给两台电脑配置IP、子网掩码和网关,必须要配置到同一个网络中。

这样我们就构建好了一个最简单的局域网了。

image-20200726223529480

1.3.2.1、封装

所谓封装,就是每一层都会根据用到的协议,把数据封装成最终的一个数据单元(不同分层有不同的叫法,参考上图最左边每层的描述),每一层拿到的上一层的内容,把上一层封装好的内容作为当前层的数据,然后加上自己的协议头或者尾,接着执行该层协议的相关处理逻辑。

有没有发现,这有点像装饰者模式,每一层拿到上一层的内容之后都添加额外的处理逻辑,但是不改变上层传过来的内容。

image-20200726223316970

如上图,左边部分为封装的过程:

  • A主机请求B主机的HTTP服务,应用层使用HTTP协议对请求内容进行封装,加上HTTP请求头,然后传给下一层;
  • 传输层拿到HTTP数据,使用TCP协议进行处理,加上自己的TCP头,封装成数据段,通过TCP协议传输给下一层。这一层通过TCP协议保证了可靠的传输
  • 网络层拿到TCP传输段之后,使用IP协议进行处理,加上IP头,封装成包进一步传给下一层。这个IP决定了什么路由或者主机需要接收处理这个包;
  • 数据链路层拿到网络层的包之后,进一步封装成数据帧,最终通过数据链路层进行发送处理,最终数据帧通过物理层传输给接收端。

1.3.2.2、分用

所谓分用,指的是主机或者中间设备接收到一个物理层传输过来的数据帧时,数据开始从协议栈中由底向上升,逐层处理,每层去掉对应的协议的报文首部。每层协议盒都要检查报文首部的协议标识进行对应的协议处理。

image-20200726223316970

在上图中,右边部分为分用的过程:

  • 主机B接收到物理层传过来的数据帧之后,首先从首部找到MAC地址,判断是否发送给自己的,如果不是则进行丢弃;
  • 如果发送包是自己的,则从数据帧确定数据协议类型,再传给对应的协议模块,如IP、ARP等;
  • IP模块接收到数据后获取IP首部判断首部接收的IPIP地址匹配,如果匹配则根据首部协议类型转发给对应的模块,如TCP、UDP等;
  • 传到TCP模块之后,首先TCP模块会计算校验和,判断数据的完整性,然后处理数据包的顺序接收相关逻辑;最后检查端口号,确定具体应该要转发给应用层的哪个应用程序。
  • 应用层接收到数据之后,解析数据进行展示,这里是HTTP数据包,所以按照HTTP协议的约定进行解析展示。

可以发现,以上流程中,大家感知最深刻的就是传输层的TCP或者UDP协议,以及应用层的HTTP协议了,因为做网站开发,或者网络通信编程经常会用到它们的API。

上面介绍的并不是很详细,不过没关系,后面我们会把主要的协议都拿出来详细的讲解。

当然,正常的网站请求中,中间肯定会涉及到很多路由器,交换机,光纤等底层的物理设备,中间会产生很多的逐跳(Hop-by-hop),每个中间系统都会对数据帧进行分用和封装的过程。

1.4、TCP/IP协议簇

TCP/IP协议簇内容非常多,这里列出的是本文可能会介绍到的相关协议,以及他们之间的交互关系:

image-20200726204748249

2、物理层

我们的数据帧究竟是怎么传给不同的主机呢。前面我们了解到每一个上层都依赖于下层的API,而物理层是最底层的了,它是真的要把数据传出去了。而数据最终都会变为0和1,物理层依赖于各种不同硬件技术,通过网络的电子传输技术,把0和1在传输介质中进行传输。

2.1、通信系统的模型

下我我们举一个最简单的例子来说明通信系统的模型[1]

很久以前,有些同学家里都是用的电话线进行上网的,这种网络传输模型类似如下这样:

image-20200712230429639

如上图,主要包括源系统,传输系统,目的系统,可以抽象为下半部分的模型:

  • 源点:源点产生要传输的数据;
  • 发送器:源点产生的数据经过发送器编码之后进行传输;
  • 传输系统:传输系统可能是简单的传输线,也可能是复杂的网络系统;
  • 接收器:接收传输系统的信号,转换为能够被目的设备处理的信息;
  • 终点:从接收器获取传送过来的数字比特流,最终输出信息。

2.2、物理层解决什么

传输媒介的种类非常多:双绞线、对称电缆、同轴电缆、光缆、无线信道等,导致物理层的协议种类较多。

物理层的主要作用是屏蔽掉这些传输媒介和通信手段的差异,使物理层上面的数据链路层感觉不到这些差异。为此,物理层需要处理以下事情

  • 规定接口所用接线器的形状和尺寸,引脚数目和排列,固定和锁定装置等;
  • 规定接口电缆各条线上的电压范围;
  • 规定某一电平电压的意义;
  • 规定不同功能的各种可能事件出现顺序。

2.3、物理层也出面试题?

最后我列几个物理层常见的面试题,一般的开发人员都是工作在传输层以上,所以考一些TCP,UDP,HTTP,HTTPS等协议我觉得更贴近开发人员真实的工作场景。当然,如果是通信领域的工程师,物理层都是家常便饭,这些可是通信的基础知识。即使知识应用开发工程师,了解这些也不会吃亏,说不定哪天亲戚还需要叫你帮忙拉网线呢。

下面是几个常见的物理层面试题:

有哪些通信交互方式?单工、半双工通信、全双工通信?

单工通信,又称为单向通信,只有一个方向的通信,如无线电广播,电视广播;

image-20200712122203747

半双工通信,又称为双向交替通信,双方都可以收发信息,只能交替进行;

全双工通信,又称为双向同时通信,双方可以同时发送和接收数据。

image-20200712122339778

为了提高信道利用率,有哪些信道复用技术?

所谓信道复用技术,指的是大家共享一个信道进行通信,在接收端在使用分用器,把合起来传输的信息分别送到相应的终点;

频分复用

用户在分配到一定的频带后,通信过程中使用都占用这个频带;

image-20200712123343946

时分复用

将时间划分为一段段等长时分复用帧,每一个时分复用的用户周期性的占用帧位;

image-20200712123728888

统计时分复用

时分复用,如果用户没有任何数据要传输,也会周期性的给他分配时隙,这就导致了信道利用率不高。

为此出现了统计时分复用。

统计时分复用使用STDM帧来传送复用的数据,把所有用户数据按时间顺序组成STDM帧,放入一个队列中,依次发送出去,这样就能够更合理的共享信道。STDM帧中的数据需要添加用户地址首部信息,以便能够正确的分发给目标用户:

image-20200712130521935

这里的集中器也叫智能复用器。

除了以上三种,还有波分复用和码分复用,感兴趣的朋友可以自行搜寻资料了解,这里就不继续展开来讲了。

物理层要解决什么问题?

这个问题上一小节已经回答了。

2.4、物理层设备之集线器

如果我们只是想用几台电脑搭建一个局域网,那么可以通过集线器(Hub)进行搭建,这个硬件工作在物理层,会把自己收到的字节都复制到其他端口,如下图:

image-20200712162725654

如上图,其中一台电脑发送信息之后,Hub以广播的方式发给其他三台机器,但是究竟哪台电脑才会把消息接收下来呢?这里我们就要讲到数据链路层了,在这一层判断数据包是不是自己的。

3、数据链路层

3.1、数据帧格式

我们首先来看看数据链路层的传输数据帧的格式。

所有的以太网(802.3)帧都基于一个共同的格式。在原有规范的基础上,帧格式已被改进以支持额外功能。

当前以太网的帧格式[2]如下:

image-20200715085955337

前导:用在发送方和接收方之间同步时钟和bit流;

SFD:帧开始界定符,只有一个byte,内容固定为:10101011 (0xAB);

DST:目标MAC地址;

SRC:源MAC地址;

长度或类型:0800时,表示IP数据报,0806表示ARP请求/应答,0835表示RARP请求/应答;

FCS:帧检验序列,用于数据帧的差错检测;

这个包应该发给谁?

判断是否应该接受这个包,就是通过帧的MAC地址进行判断的。

这是一个物理地址,叫做链路层地址,因为链路层主要解决媒体接入控制问题,所以称为MAC地址(Media Access Control Address)。实际上,MAC地址就是适配器地址或适配器标识符,当适配器插入到某台计算机之后,适配器上的标识符就成为这台计算机的MAC地址了。

怎么校验包是否出现错误

FCS是帧校验序列,也就是循环冗余检测,收到数据报之后,会通过一个检验计算规则,把计算结果与FCS字段匹配,如果匹配补上,则帧可能在传输过程中受损,通常会丢弃该帧。

3.2、ARP: 如何获取目标机器的MAC地址?

我们知道,在数据链路层,是通过MAC地址判断某一个接收到的包是不是要进一步处理的。但是如果我们不知道对方的MAC地址的时候,如何发送数据链路层的帧呢?这就需要用到数据链路层的ARP协议了。

ARP协议:ARP为IP地址到硬件地址之间提供了动态映射,我们通过ARP可以把32位的Internet地址转换为48位的MAC地址。另外,我们可以使用RARP,把48位的MAC地址转换为32位的Internet地址。

image-20200713220351269

另外,为了保证ARP的高效运行,ARP会维护每个主机和路由器上的ARP缓存,把Internet地址和MAC地址的映射关系保存起来,缓存正常到期时间是20分钟。

下面是这个过程的演示,其中ARP数据帧只把关键信息描述出来了,想要了解完整的帧格式可以用参考 TCP/IP协议详解卷1[3]

image-20200713231114251

如上图:

主机A想知道192.168.1.4这个IP地址的MAC地址是什么,发现本地缓存中找不到,于是广播了一个ARP请求,主机B和主机D收到之后,发现自己不是192.168.1.4于是忽略这个消息,主机C发现自己就是192.168.1.4,于是响应了一个ARP数据帧。最终主机A收到主机C响应的数据帧,拿到了MAC地址,并把IP地址和MAC地址映射关系保存下来。

3.3、链路层设备之交换机

3.3.1、为什么需要交换机?

前面我们用了集线器组件网络,这个时候所有消息都会广播到其他端口,可以发现集线器转发了很多不必要的消息,能不能只发给需要的端口呢?这个时候就需要用到交换机了。

当一台电脑A向交换机发送数据时,交换机会把电脑A的IP和MAC地址记住,保存到一个转发表中,如果转发表中暂时找不到目标IP地址的MAC地址,那么首先还是会广播消息,最终转发表会记录所有请求过交换机的电脑IP和MAC。当然,转发表也是有过期时间的。

image-20200713232323689

如上图,看到交换机的奸笑没有,与集线器不同,交换机是有灵魂的的,你告诉他你的身份证号和住址了,他就会偷偷记下来。

3.3.2、为什么有了IP地址,还需要有MAC地址?

IP地址是工作在网络层的,后面会讲到;

MAC地址是工作在数据链路层的,也就是交换机这一层,交换机之间的主机进行通信,都是用的MAC地址,但是一旦走出了局域网,我们就得用大家都公认的IP地址了。

MAC地址就好像是我们的身份证,IP就像是我们的住址,可以根据住址寄送快递,但是不能根据身份证号码寄快递,别人不知道怎么走呢。

一个局域网,用身份证没有问题呀,因为要找某个人,ARP会大喊一声名字,那个人就会告诉你他的身份证号码了,这个时候直接以身份证作为标识传消息,别人听到不是自己的身份证就不管了。最终交换机这个小管家记住了所有人的名字跟身份证号码,就会使用悄悄话的方式传达消息了。这也就是用到了交换机的转发表。

3.3.3、交换机拓扑环路问题

假设我现在拉网线,搞了一个这样的拓扑结构:

image-20200714225908316

如上图,主机准备发送一个消息出去,结果交换机B收到后,复制数据帧,发送给了交换机A、C、D,此时交换机B认为主机是在左边。但是不妙的事情发生了,交换机D收到消息后,由于转发表还是空的,又是也复制数据帧,转发到了交换机A、B、C,这个时候交换机B发现怎么主机的数据又从右边传过来了,这些彻底晕了,不知道主机究竟在哪里。就这样数据一致在这个网络里面打转,这就拓扑环路导致的问题。

生成树协议

为了解决以上问题,于是 有了生成树协议(Spanning Tree Protocol,STP)。

STP通过在每个交换机禁用某些端口工作,来避免拓扑环路,保证不会出现重复路径。

STP会找到拓扑结构的一个生成树,通过生成树避免环路。生成树的形成和维护有多个网桥完成,在每个网桥上运行一个分布式算法。

以上拓扑,结构,最终应用了生成树,禁用一些端口之后,可能会是这样:

image-20200714225935282

这样,消息就不可能再传回左边的主机了,从而避免了拓扑环路导致的问题。

建立生成树:

网桥会发送一种称为网桥协议数据单元(BPDU)的帧来辅助形成和维护生成树。

STP首先会尝试选举根网桥,根网桥是在网络中标识符最小的网桥(也就是说优先级与MAC地址结合),网桥初始化的时候,假设自己是最小的网桥,然后用自己的网桥ID作为根ID字段的值发送配置BPDU消息,如果发现ID更小的网桥,那么会停止发送自己的帧,并基于接收到的ID更小的帧构造下一步发送的BPDU消息。发出根ID更小的BPDU端口被标记为根端口,剩余端口被设置为阻塞或者转发状态。

3.4、VLAN

3、网络层

网络层,Internet layer,最熟知的就是IP协议了(Internet Protocol)。

前面我们将的数据链路层,其实只能在局域网内进行通信,因为都是通过MAC地址进行传达信息的,要想跨局域网,那么就得用到IP地址了,这就是网络层要做的事情了。

首先我们来介绍下网络的一个协议:ICMP协议。

3.1、ICMP协议

IP协议本身不支持发现发往目的地地址失败的IP数据包,也没有提供直接的方式获取诊断信息,比如在发送途中,经过了哪些路由器,以及往返时间。

为此,就有了ICMP协议Internet Control Message ProtocolICMP)专门来负责这些事情。

ICMP并不为IP网络提供可靠性,它只是用于反馈各种故障和配置信息。丢包不会触发ICMP。

ICMP是RFC 792中定义的Internet协议套件的一部分。ICMP消息通常用于诊断网络或探测网络目的,或者是为了响应IP操作中的错误而生成(如RFC 1122中所指定),ICMP错误响应给原始数据包的源IP地址。

但是黑客经常用ICMP来做坏事,于是网络管理员可能会用防火墙阻止掉ICMP报文,这样的话,很多ping、traceroute之类的诊断程序就无法正常工作了。

3.1.1、格式

ICMP报文是在IP数据报内部传输的,格式如下:

image-20200715084813447

而ICMP报文的格式如下:

image-20200715085522615

其中:

  • 类型有15个不同的值,描述特定类型的ICMP报文;
  • 某些ICMP报文还是用代码字段的值来进一步描述不同的条件;
  • 校验和字段用于ICMP报文的差错检查。

以下是常见的差错报文类型:

类型 代码 描述 查询 差错
0 0 回显应答(ping应答)
3 目标不可达
0 网络不可达
1 主机不可达
2 协议不可达
3 端口不可达
4 需要进行分片但设置了不分片比特
5 源站选路失败
6 目的网络不认识
7 目的主机不认识
8 源主机被隔离(作废不用)
9 目的网络被强制禁止
10 目的主机被强制禁止
11 由于服务类型 T O S , 网 络 不 可 达
12 由于服务类型 T O S , 主 机 不 可 达
13 由于过滤,通信被强制禁止
14 主机越权
15 优先权中止生效
4 0 源端抑制
5 重定向
0 对网络重定向
1 对网络重定向
2 对服务类型和网络重定向
3 对服务类型和主机重定向
8 0 回显请求(ping)
9 0 路由器通告
10 0 路由器请求
11 超时
0 传输期间生存时间为0(Traceroute)
1 在数据报组装期间生存时间为0
12 参数问题
0 坏的 I P 首部(包括各种差错)
1 缺少必需的选项
13 0 时间戳请求
14 0 时间戳应答
15 0 信息请求
16 0 信息应答
17 0 地址掩码请求
18 0 地址掩码应答

其中,最常用的类型是8:回显请求(ping),以及0:回显应答(ping应答)。

3.1.2、查询报文

查询报文是有关信息采集和配置的ICMP报文。

我们经常用到的ping程序就用到了ICMP查询报文。

ping程序

ping程序会发送一份ICMP回显请求给主机,并等待返回ICMP回显应答。

ping程序ping不通了,就不能访问对应的主机了吗?

我们知道,网络管理员可能会用防火墙阻止掉ICMP报文的,这样我们可能就ping不通了,但是主机的可达性不能只取决于IP层是否可达,还与端口号和协议有关,而ping是运行在网络层的,用于测试网络连接状态和信息包发送接收状况,即使ping不通,我们也可能用telnet远程登录到主机的其他端口,如25号端口。

ping程序用到了回显请求和回显应答报文,报文格式如下:

image-20200715233138672

Unix系统实现ping程序时,把ICMP报文的标识符设置为进程ID,在进程内,序号从0开始,每发送一次新的 回显请求就加1,这样就可以同时运行多个ping进程了。

ping程序的端口号是什么?

端口号是传输层的东西,ping程序是使用ICMP协议,直接跳过了传输层,所以呢,ping程序是没有所谓的端口号的。

我们发送一个ping请求,数据在协议栈中的处理流程如下:

image-20200716085927626

  1. A主机的ping应用程序向服务器发起回显请求,说了一句:hi
  2. 直接传输到网络层的ICMP协议,进行ICMP数据封装:
    1. image-20200716085942614
    2. 8表示回显请求,112是发起请求的进程号,1表示请求序号
  3. IP协议拿到数据后进一步加上IP头,加上自己的IP和目标IP,传输给数据链路层;
  4. 数据链路层拿到IP数据包,准备封装成帧,这个时候会去寻找目标IP的MAC地址,如果在A主机的ARP映射表找到了IP的MAC地址,那就直接拿来用了,否则会发起一个ARP广播请求,获取到MAC地址。至于跨网关这种ping,会多了转发的功能更,后面会进行介绍。最终数据链路层封装成数据帧,从网络接口发出去;
  5. 服务器拿到数据帧之后,拿到MAC头,判断MAC地址是自己的,就基于拿到Frame data,按首部协议传给对应的模块,即IP模块;
  6. IP模块拿到数据,判断到IP跟自己对上了,与是继续拿到IP data,传输给ICMP协议,ICMP协议收到消息,准备应答:
    1. image-20200716085953616
    2. 0表示回显应答
  7. 然后按照同样的流程,把数据包发送回A主机。

可以发现,ping程序是直接用到了网络层的ICMP协议,不经过传输层

是什么原因导致ping失败了?

ping失败的原因有很多:

  • 可能是输错了IP;
  • 可能是网络配置不正确,如错误的子网掩码;
  • 可能有防火墙软件组织了ping;
  • 可能是硬件故障,如损坏了的以太网适配器,电缆,路由器,集线器等。

如果叫你自己实现一个ping程序,你会怎么做呢?

提示:为了能处理ICMP网络报文,我们需要用到原始套接字(SOCK_RAW),而不是SOCK_STREAM或者SOCK_DGRAM套接字。

更多提示:Homework 6: A raw socket ping tool[4],思路都在这里了,大家动手做一做,然后就可以有直接操作网络层的工作经验了。

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/arthinking/p/13429848.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!