对于同一台设备上的进程间通信,有很多种方式,比如有管道、消息队列、共享内存、信号等方式,而对于不同设备上的进程间通信,就需要网络通信,而设备是多样性的,所以要兼容多种多样的设备,就协商出了一套通用的网络协议。
TCP/IP 网络模型是分层的,接下来我们看看每一层的作用。
首先是应用层,应用层处于这层模型的最上层,是我们可以直接接触到的部分,和字面意思一样,就是我们使用的应用层面,不过和我们想的不太一样,应用层只是为应用提供一个较好的功能平台,比如提供HTTP等网络服务,其实并不是跑应用的一个层,实际的理解应该是两个不同设备的应用想要通信需要依赖于这个层,所以才叫应用层。
比如,我们建立一个网站,它本身并不是应用层的,但是它是在应用层基础上运行的。应用层的协议确保了不同应用之间能够理解彼此的请求和响应,从而实现数据的交换。
或者我们可以这样说,实现了比如 HTTP、FTP、Telnet、DNS、SMTP等等引用层协议的应用层上跑的应用才能和其他设备上同样实现了这些协议的应用层上跑的应用交互。
应用层是工作在操作系统中的用户态,传输层及以下则工作在内核态。这个很好理解,本来用户态就是跑应用的,应用层上跑应用自然是在操作系统的用户态。
但是怎么才可以使得抽象层次非常高的应用层实现交互呢?这就得看我们的传输层了。
应用层把数据整理好了之后会发送给传输层,让它做进一步的包装,这里一是为了方便另一端到时候可以分层解包,二是方便加料。
传输层有两个我们十分熟悉的传输协议,分别是TCP和UDP,前者是可靠传输,后者是实时传输。相较于后者,TCP会将传输层的数据包进行分块,而且是当传输层的数据包大小超过MSS(Maximum Segment Size,TCP 最大报文段长度)之后才会将数据包分块,分块的目的是避免数据包在传输的过程中损坏或丢失重传整个数据包,分块之后我们只需要重传一个分块即可,而且这些块在TCP协议中也有特殊的称呼,被称为TCP段(TCP Segment)。但是UDP不实现可靠传输,就不会对数据进行分块了,它是直接将应用层发送的数据作为一个整体打包成数据报,发送给下层,省去了分块的时间,所以效率很高。
TCP相较于UDP有了更多的特性,常见的比如有流量控制、超时重传、拥塞控制等,这个在TCP报文中就有相应的体现,我们之后就会看到。
另一边在接受时,由于有多个软件同时在运行,传输层此时要将数据包传递到上层,与之前不一样,之前直接往上层一扔就行了,但是此时由于等待接收数据的对象太多了,我们需要将数据包对号入座,因此需要一个编号将应用区分开来,这个编号就是端口。
突然发现我们可以把这个TCP/IP架构看为一棵树,树上的叶子节点是软件程序,然后数据包可以看做是细胞传递的物质,一层包一层,胞吐到下一个细胞。至于这个端口就是每个树枝,树枝末端才是在计算机上跑的软件。
应用层不跑应用,传输层不传输数据。
传输层不传递数据,那么到底是哪一个层传递数据呢?
那当然是网络层了,网络层使用的最多的是IP协议,IP 协议会将传输层的报文作为数据部分,再加上 IP 报头组装成 IP 报文,如果 IP 报文大小超过 MTU(Maximum Transmission Unit,网络中一个数据包所能达到的最大字节数,以太网中一般为 1500 字节)就会再次进行分片,得到一个即将发送到网络的 IP 报文。
这里注意一下,MSS只包括数据块那一部分的数据,而MTU则包含了IP头部,TCP头部,再加上数据块的长度,它们的大小不一样。
IP地址有两种含义,一种是网络号,一种是主机号,这里又有一点类似树的味道了,网络号也就是标识着这个IP地址是属于哪一个子网的,是父节点,然后这些主机号,也就是这个子网下的不同主机,则是叶子节点。
那么我们如何计算出IP地址的网络号和主机号呢?
当然是配合掩码来计算,我们直接按位与计算就行了。
那么在寻址的过程中,一般会先匹配到相同的网络号(表示要找到同一个子网),才会去找对应的主机,其实和找树节点很类似。
所以,IP 协议的寻址作用是告诉我们去往下一个目的地该朝哪个方向走(也就是找子网),路由则是根据「下一个目的地」选择路径(这就是路由器的工作)。寻址更像在导航,路由更像在操作方向盘。
这里有点不太好理解,其实路由器内部是维护了一张路由表的,记录了到达某一个子网需要走的路径,可以和生活中向别人问路结合起来想,其实IP地址就是我们要到达的目的地,然后依据着这个东西一路问下去,我们就可以到达终点。当你想发送数据时,路由器会查看目标IP地址,查找路由表,决定将数据包发送到哪个下一跳(另一个路由器或设备),直到数据包最终到达目的地。
网络层处理完成之后还不能直接发送,还要经过网络接口层的处理(网络接口层通常指的是数据链路层,我是说为什么之前没了解到这个东西),也就是说,我们要在IP头部的前面加上MAC头部,然后封装成数据帧,再发送到网络上,在局域网中进行传输。
IP 头部中的接收方 IP 地址表示网络包的目的地,通过这个地址我们就可以判断要将包发到哪里,但在以太网的世界中,这个思路是行不通的。
以太网在判断网络包目的地时和 IP 的方式不同,因此必须采用相匹配的方式才能在以太网中将包发往目的地,而 MAC 头部就是干这个用的,所以,在以太网进行通讯要用到 MAC 地址。
感觉以太网就是树根,树根的不同小枝代表了不同的MAC地址,小枝上的细毛代表着不同的IP地址,这里只是又套了一层而已。
MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息,我们可以通过 ARP 协议获取对方的 MAC 地址。
所以说,网络接口层主要为网络层提供「链路级别」传输的服务,负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标识网络上的设备。
网络接口层的传输单位是帧(frame),IP 层的传输单位是包(packet),TCP 层的传输单位是段(segment),HTTP 的传输单位则是消息或报文(message)。但这些名词并没有什么本质的区分,可以统称为数据包。
这里再补充一些其他的知识:
这里补充一下什么什么网之间的区别
只要是有两个设备可以相互传送数据,那么就可以说它们组成了一个计算机网络
lan是接下层网络的,wan是接上层网络的
局域网范围很小,理解为一个家庭的网络就可以了
只要是这个网络中所有设备可以相互通信,那么就可以说它们形成了一个计算机网络
这个有点类似多叉树的结构,还有一点就是有点电路连线的味道
局域网,广域网,城域网其实就是范围的不同,一般到了小区的这个层面就是城域网了
交换机的插口比路由器的插口多的多,一般是多个lan口,一个wan口
城域网由多个局域网组成,广域网由多个城域网组成
之所以我们生活中的电脑可以互相通信,这是因为我们的祖先交换器是一样的,可以顺藤摸瓜把数据发送到另外一台电脑上
我们上网就是上因特网/互联网,Internet是一个特殊的广域网,是最大的广域网,使得世界上所有的电脑可以互相通信
但是以太网和上面的都不同,以太网是一门技术,比如是以太网的这个技术构成了局域网,A和B之所以可以通信是靠以太网这个技术实现的
局域网使用的技术是以太网,所以局域网又可以称为以太网
接下来再补充一下IP地址和MAC地址的区别
用邮件来作为类比,MAC地址就是收件地址,IP地址就是收件人,如果把网络比作城市的话,那么网卡就是城市中的建筑,MAC地址就是这栋建筑的物理地址,IP地址就是在这些建筑中的人。
但是和实际的写信不同,在计算机网络中发送消息,我们只用填写内容和对方的IP地址即可,操作系统会根据对方的IP自动查寻ARP表获取对方的MAC地址,然后再由网卡将这封信发出。
ARP协议具体就是在不知道对方的MAC地址时先在局域网内发送一包ARP广播报文出去,询问对应IP的MAC地址是什么,只有对应IP的设备才会回复这个请求,所以就会得到对方的MAC地址,把这封信补全再发出去。
虽然有很多种的电子产品,但是实际上它们的通信都是由内部的网卡设备所进行的,所以我们可以统一用网卡来表示设备,每张网卡出厂时都会被写入一个MAC地址,由6个字节构成,其中三个数表示网络硬件厂商编号,后面三个数表示网卡序列号,它是全球唯一的。
MAC地址确定了网卡在网络中的确定位置,但是我们的网卡在接入网络之后想要通信还要配置另外一个地址,也就是IP地址,但是一般我们的电脑接上网线,或者手机连上路由器之后不用配置IP地址也可以正常使用,这是因为DHCP协议,自动帮我们配置了,动态分配IP地址给我们。
当我们的电脑插上网线或者手机连上WIFI,操作系统协议栈会自动向外发送一个DHCP请求,路由器接送到这个请求之后会为其动态分配一个IP地址,并通过DHCP回复报文回复回去。操作系统收到后,会将这个IP地址配置到网卡上。
还有就是交换机与路由器之间的区别
交换器相当于邮递员,根据数据包中的目标MAC地址,找到它对应的物理端口,正如我们前面所看到的,一台交换机有很多个端口,它们都有自己的编号,计算机的网卡通过网线连接到交换机的网口上,这个端口就是一个确定的物理地址,我们只需要知道某个网卡的MAC地址在哪个端口上就可以将数据包发送给它。
在交换机中,有一张端口与MAC地址的映射关系表,称为MAC地址表,我们只需要知道对方MAC地址在哪一个端口上,然后顺着对应的端口发送出去即可,找到的话会直接从关联端口发出,未查到的话会泛洪群发。
所以交换机只会关心MAC地址,不会关心IP地址,MAC地址在TCP/IP协议栈中处于第二层数据链路层,所以交换机也被称为二层设备。
路由器有两种端口,分别是LAN口和WAN口,LAN口一般会有多个,用于连接家庭的网络设备,WAN口只有一个,用于连接到Internet因特网上。
我们忽略WAN口的话,其实路由器就是交换机,加上WAN口的话,就是网关。
所以实际在发送数据包的时候,还会根据是不是同一个子网采取不同的发送策略,是同一个子网就直接发出,不是同一个子网,就将目标MAC地址改为网关地址MAC发出,通过网关的路由表来查询,再将目标MAC覆盖为实际目标的MAC地址,源MAC地址改为自己网关的MAC地址。
这上面的行为就是路由,根据目标的IP来判断如何发送。
路由器有一个WAN口接入互联网,有多个LAN口接入本地网络,它们就属于两个不同的子网,所以这里就要由路由器担任网关的作用,来路由数据包。
简单的说,路由器是为了局域网之间进行通信,交换机是为了局域网内进行通信。
再接下来介绍一下源地址转换和目标地址转换
我们在前面已经知道了,数据包如何发送是根据IP来进行路由的,但是我们在内网中可以有相同的IP地址,那么就会导致ARP表混乱,那么我们是如何解决这个问题的呢?
源地址转换技术SNAT(SNAT,Source Network Address Translation)是一种用于解决内网IP地址冲突问题的技术。它允许多个内网设备使用相同的私有IP地址通过一个公共IP地址与外部网络通信,从而有效地管理IP地址和避免ARP表混乱。
本质就是多加一些信息,多加一些标识。
目标地址转换技术DNAT(DNAT,Destination Network Address Translation)主要用于将外部请求转发到内部网络中的特定设备。
这个则是有一些端口映射的关系,和Docker有点类似。