👦个人主页:Weraphael
✍🏻作者简介:目前正在学习c++和算法
✈️专栏:Linux
🐋 希望大家多多支持,咱一起进步!😁
如果文章有啥瑕疵,希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注😍
前言
计算机网络是现代计算机技术和通信技术密切结合的产物,是随着社会对信息共享和信息传递的要求而发展起来的。所谓计算机网络是指利用通信设备和线路将地理位置不同的功能独立的多个计算机系统互联起来,以功能完善的网络软件,如网络通信协议、信息交换方式以及网络操作系统等,实现网络中信息传递和资源共享的系统。
总之,系统负责数据的处理和管理,而网络负责数据的传输和连接。二者相辅相成,共同支持现代计算环境的运行。
目录
- 前言
- 一、网络的发展
- 二、局域网和广域网
- 三、网络协议
-
-
- [2.1 什么是协议](#2.1 什么是协议)
- [2.2 协议分层](#2.2 协议分层)
- [2.3 OSI七层模型](#2.3 OSI七层模型)
- [2.4 TCP/IP五层(四层)模型(TCP/IP协议栈)](#2.4 TCP/IP五层(四层)模型(TCP/IP协议栈))
- [2.4 操作系统与TCP/IP协议栈的关系](#2.4 操作系统与TCP/IP协议栈的关系)
-
- 四、网络传输
-
-
- [3.1 同局域网的两台主机通信](#3.1 同局域网的两台主机通信)
- [3.2 局域网/以太网通信原理](#3.2 局域网/以太网通信原理)
- [3.3 跨网络的两台主机通信](#3.3 跨网络的两台主机通信)
-
- 五、网络地址
-
-
- [5.1 IP地址](#5.1 IP地址)
- [5.2 MAC地址](#5.2 MAC地址)
- [5.3 IP与MAC的关系](#5.3 IP与MAC的关系)
-
一、网络的发展
早期的电脑多为独立模式 。独立模式本质就是计算机之间相互独立,在这种模式下,计算机之间的通信依赖于物理媒介,如软盘、硬盘等。
正因为计算机之间是相互独立的,此时如果多个计算机要协同完成某种业务,那么就只能等一台计算机处理完后再将数据传递给下一台计算机,然后下一台计算机再进行相应的业务处理,效率非常低下。
从20
世纪60
年代中期开始,出现了若干计算机互联系统,开创了"计算机 - 计算机"通信时代。20
世纪60
年代后期,以美国国防部资助建立起来的阿帕网 (Advanced Research Projects Agency network,ARPANET
)为代表,从此标志着计算机网络的兴起。
因此,随着联网和网络计算的普及,使得多台计算机通过网络连接在一起 ,以便进行数据共享、通信和资源协作,从而实现网络互联。
二、局域网和广域网
后来这样的网络雏形逐渐发展,连入这个网络中的机器变得越来越多,于是就出现了局域网Local Area Network - LAN
和 广域网Wide Area Network - WAN
。
- 局域网
LAN
:是一种在有限区域内(如家庭、办公室或校园)将计算机通过交换机和路由器连接在一起。- 交换机:负责接收和转发数据帧,将数据发送到目标设备。
- 路由器:处理网络之间的通信。
- 广域网
WAN
:是一种覆盖广泛地理区域的网络,连接不同城市、国家或甚至大陆上的计算机和设备。即将远隔千里的计算机都连在一起。
所谓的局域网和广域网只是一个相对的概念。说白了就是一个网络在某些条件下可以被视为局域网,在另一些条件下则可能被视为广域网。例如,某个大型企业的网络可能在全球范围内分布,作为广域网的一部分,但在企业内部的特定区域可以被认为是局域网。
三、网络协议
2.1 什么是协议
协议的本质是双方(或多方)对如何进行通信或数据交换达成一致的约定。这种一致性确保了在交互过程中双方能够正确理解和处理对方发送的数据。因此,我们可以说 协议本质就是一种约定。
计算机之间的传输媒介是光信号和电信号,光信号和电信号通过不同的"频率"和"强度"来表示二进制信息(0
和1
),要想传递各种不同的信息,就需要约定好双方的数据格式。这就是一种纯硬件的一种约定方案。
如何理解计算机层面上的协议?
比方说,当我们给对方寄快递的时候,快递单就是双方的协议,而快递盒子里的物品就是数据。快递单上会有双方的地址、电话等信息,而这些信息在协议中称为协议报头 。一般来说,协议报头包含以下几个基本组成部分:源地址、目的地址、协议类型等信息。因此,用户收到的不止是数据,是数据 + 报头
所以,我们可以使用计算机语言中的结构体struct
来描述协议报头字段,从而定义出来一个协议。
以C
语言为例,一个简单的协议报头结构体可能如下所示:
cpp
#include <stdint.h>
// 定义协议报头结构体
typedef struct
{
uint16_t source_port; // 源端口号
uint16_t destination_port; // 目的端口号
uint32_t sequence_number; // 序列号
uint32_t acknowledgment_number; // 确认号
uint8_t data_offset; // 数据偏移量
uint8_t flags; // 标志位
uint16_t window_size; // 窗口大小
uint16_t checksum; // 校验和
uint16_t urgent_pointer; // 紧急指针
} ProtocolHeader;
使用结构体来定义协议报头字段,能够确保在多台主机之间的通信中,数据格式和解释是统一的。通过结构体,我们可以确保协议的每个字段都有明确的定义,使得发送方和接收方能够以一致的方式理解和处理这些数据。这种一致性对于网络协议的设计至关重要。
总结:协议可以看作是双方在通信中达成的约定,而在计算机系统中,这些协议往往通过结构体来具体实现的。
只要通信的两台计算机约定好协议就可以了吗?
计算机生产厂商有很多、计算机操作系统的种类也很多、计算机网络硬件设备还是有很多等等。那如何让这些不同厂商之间生产的计算机能够相互顺畅的通信? 就需要有人站出来,约定一个共同的标准,大家都来遵守, 这就是网络协议。
那么协议应该由谁来制定?
网络协议的制定通常由标准化组织、行业协会、技术社区和其他专业机构来完成。这些组织和机构一定是该领域当中的佼佼者,因为网络协议的定制本质就是规则的定制。
比方说, 国际标准化组织(ISO
) ,它制定的 OSI
模型 是网络通信领域的重要框架。这个模型将网络通信分为七个不同的层次,每一层都有特定的功能和协议。这个模型可以帮助我们理解和设计网络通信系统中的各种功能和协议。(过后会带大家看看七层结构)
2.2 协议分层
在计算机领域中,协议就是用来解决通信问题 ,以下网络在传输过程中面临诸多问题:
- 如何保证数据能准确到达下一个设备(如中间设备路由器、交换机等)问题。
- 如何定位目标主机问题。
- 长距离传输,数据丢失问题。
- 如何处理发来的数据问题。
注意:发送方有以上问题,接收方也一定会有这些问题(对称关系)
为什么会有这些问题呢?
我们先前说到过:大部分的计算机都遵守冯诺依曼体系。
内存、输入和输出设备、CPU
都是硬件,那这些硬件是如何交互的呢?
这些设备间一定要有 "线" 连接起来。这些设备在一台机器上,线比较短。
IO
总线: 外设和内存连接的线。- 系统总线:
CPU
和内存连接的线。
若此时有两台机器呢?这两台计算机要互相通信,那么也需要用"线"连接起来。
计算机体系结构本质也可以被看做成为一个小型网络,其内部通过 "线" 连接起来,而多主机连接,本质上其实也是通过 "线" 连接起来的,这根线即网线。
主机内,"线" 比较短,会面临信号干扰的问题;如果是跨主机的话,"线"比较长,那么就会面临刚刚我们说的那四个问题。所以,出现这些原因就是 单纯的传输距离变长了!!!
如何解决这些问题呢?
此时网络的层状结构(又称网络协议栈)呼之欲出 ,不同分层中包含了各种协议,负责解决不同的问题。
分层的好处?
其实分层这个概念在以往学习的过程已经接触过了。比方说:
Linux
操作系统本身就是分层的
-
继承和多态。在继承中,多态允许通过父类(上层)的引用或指针来调用子类(下层)中的方法,虽然编译时不知道具体的子类,但运行时会调用子类的实际实现。
-
生活例子:打电话。
在逻辑上,我们打电话的时候都认为是在和对方沟通;但站在工程师的角度,实际双方并不是直接进行沟通的,而是和电话进行沟通。然后电话通过声音信号经过了多个层次的处理和转换,这包括:
- 采集和编码:声音通过麦克风被转换为电信号,然后经过编码处理。
- 传输:编码后的信号通过电话网络传输,可能经过多个中间设备。
- 解码和播放:到达对方的设备后,信号被解码成声音,然后通过扬声器播放出来。
其中,人与人之间通信使用的是汉语,我们可以将其称为语言层(上层);而电话和电话之间通信使用的是电话系统相关的一些接口,我们可以将其称之为通信设备层(下层)。
后来随着科技的发展,此时我们下层使用的通信设备变了,或是这部电话卖到了其他国家,此时上层使用的通信语言变了,但我们仍然可以正常沟通。
上述例子中,很好的体现出分层的好处:
- 上层关注的是信息的内容和沟通的目的,而不关心下层技术如何实现这些沟通;而下层关注的是物理连接、信号传输、网络交换等技术细节,不关心上层是如何沟通的。(每层只关注自己的功能 - 高内聚)
- 如果电话设备出现问题,作为用户,我们可能会立即想到设备故障。这是因为设备的状态直接影响到通信的质量。并且,当设备更换时,用户可以继续使用电话进行沟通,只要接口保持一致。新设备的替换不会影响到人与人之间的沟通内容。(低耦合)
因此对于网络协议栈 我们需要有一个基本的认识:在网络通信中,逻辑上我们可以认为通信双方的应用层之间直接在进行通信,也可以认为通信双方的传输层之间直接在进行通信,即层与层之间之间通信。
综上所述,网络进行分层后,不同的层负责不同的功能,互相之间不会干扰,并且每一层都有自己的协议,虽然现在大多数都是使用TCP/IP
协议,但是不能保证未来是否会推出更优的协议,所以为了未来的可维护性,进行分层也是很有必要的。除此之外,一旦在网络通信中出现了错误,分层后就能很好的定位错误出现在哪一层,进而改善一些组件。
总结:设计成层状结构的目的就是为了将层与层之间进行解耦(即层与层之间关系不紧密),保证代码的可维护性和可扩展性。本质上就是高内聚,低耦合的思想。
2.3 OSI七层模型
基于分层 的设计思想,诞生了著名的 OSI
七层网络模型。
OSI
(Open System Interconnect
),即开放式系统互连, 一般都叫OSI
参考模型,是ISO
组织在1985
年研究的 网络互连模型,该模型可以帮助不同操作系统之间实现网络通信 。OSI
模型定义了七个层次,每一层都有明确的功能和协议。
从底层到上层,OSI
参考模型 中不同层级实现功能如下所示
层数 | 分层名称 | 功能 | 每层功能预览 |
---|---|---|---|
1 | 物理层 | 解决硬件相关的问题,比如 01 序列解析、数字/模拟信号处理、界定连接器和网线的规格 |
|
2 | 数据链路层 | 解决两台主机在局域网中如何连通的问题 | |
3 | 网络层 | 解决主机跨网络,经过路径选择后如何到达目标主机的问题 | |
4 | 传输层 | 解决数据传输时可能发生的数据丢失问题,同时通过策略实现数据高效传输 | |
5 | 会话层 | 进行连接管理 | |
6 | 表示层 | 规定信息转换格式 | |
7 | 应用层 | 针对不同应用的协议 | |
OSI
参考模型 是一种框架性的设计方法,比较复杂,学习成本也比较高。因此,基于该模型可以衍生出其它的子模型,其中最出名的是 TCP/IP
五层(四层)模型,这也是我们主要学习的网络模型。
2.4 TCP/IP五层(四层)模型(TCP/IP协议栈)
为什么会变成五层模型?标准模型也能改?
OSI
模型是一个理论模型,目的是提供一个全面的网络协议框架。它涵盖了所有可能的网络通信层面。它设计的非常好,但因为复杂、学习成本高。因此,在实际应用中,有些层次的功能会被合并,而非偷工减料。
TCP/IP
模型(又称TCP/IP
协议栈)更贴近实际的网络协议实现,它在设计时注重实用性,尽量减少理论上的复杂性 。在实际网络中,应用层通常包含了会话层和表示层的功能。
为什么叫做
TCP/IP
五层(四层)模型?
这是因为 TCP
、IP
协议非常经典、非常重要,非常具有代表意义,于是就命名成了TCP/IP
五层模型。
注意: TCP/IP
是一组协议的代名词,其中包含了许多协议,共同组成了TCP/IP
协议簇。
另外,TCP/IP
五层模型也可以称为TCP/IP
四层模型,这是因为物理层的细节通常不在软件开发人员的关注范围内。
注意:并不是把物理层删了,我们可不敢修改标准。很多时候我们将物理层和链路层合并为一层。后面我们主要学习的是以上四层。
- 物理层 :负责光/电信号的传递方式 。以太网中采用同轴电缆(有线电视)、双绞线(网线)、光纤、电磁波等传递信号,不同材质决定了信号最大传输速率、传输距离、抗干扰性等。如果信号传递过程中出现衰减,还可以使用集线器进行信号增强。(了解)
- 数据链路层 :负责设备间的数据帧的传递 。比如网卡设备的驱动、帧同步、冲突检测、差错校验等工作, 数据链路层 中有很多不同的实现标准:以太网、令牌环、无线
LAN
等,具体是什么标准,取决于网卡,用于连接多台设备。实现网络数据传输与交换的交换机就工作在数据链路层。 - 网络层(重要) :负责地址管理和路由选择。比如在
IP
协议 中,通过IP
地址来标识主机,可以通过查询路由表的方式规划出源主机与目标主机之间的传输路线,这正是路由器的工作职责。 - 传输层(重要) :负责两台主机之间的数据传输。通过诸如
TCP
协议 等传输协议,实现高效、可靠的数据传输。数据传输不一定成功,可以通过重传相关机制重新传输数据。 - 应用层 :应用层是网络通信的最上层,为用户提供直接的服务和应用,依赖各种协议来实现数据的交换和处理 。比如 简单电子邮件传输(
SMTP
)、文件传输协议(FTP
)、网络远程访问协议(Telnet
) 等,在进行网络编程时,主要针对的就是应用层。举一个例子,比如说你刷抖音,那么就要获取字节服务器,字节服务器会将数据返回到你的手机上,可是数据有什么好看的,我们要看的是小姐姐跳舞。因此,应用层通过网络协议(如HTTP
)请求数据,然后对收到的数据进行解析和渲染,以便用户可以看到视频内容。
总结网络协议栈中各层的功能
- 数据链路层和物理层:要实现通信我们首先要能够将数据发送出去,而数据链路层和物理层就是负责数据真正的发送过程的。
- 网络层:在数据链路层和物理层的支持下,现在能够将数据发送出去了,但是我们还应该知道数据应该往哪里发,而网络层完成的就是数据转发,解决了数据去哪里的问题。
- 传输层:现在有了发送数据的能力,也知道数据应该往哪里发,但是我们并不能保证发出去的数据能够成功的到达对端主机,比如在传输过程中可能会出现丢包或对端主机关机,甚至对端服务器出错,导致数据传送出现问题。而传输层的工作就是处理传输时遇到的问题,主要是保证数据可靠性。
- 应用层:也就是说,网络协议栈的下三层能够保证把数据交付给对端主机,但现在我们还需要明确的是,我们将数据发送给对端主机的目的是什么,而这就是应用层要解决的问题。应用层需要根据特定的通信目的,对数据进行分析与处理,以达到某种业务性的目的。
因此网络协议栈的下三层主要的完成的工作就是处理通信细节,而应用层主要完成的就是某种具体的业务细节
2.4 操作系统与TCP/IP协议栈的关系
系统、网络不分家,看似设计复杂的网络标准模型其实和系统设计有着千丝万缕的联系。
-
应用层是位于用户层。
-
传输层和网络层是位于操作系统层。即传输层和网络层是真正意义上在内核中实现的一个模块。
-
数据链路层是位于驱动层。
-
物理层是位于硬件层。
用户想要上网,必须依赖于网卡这一硬件,但用户无法直接和硬件打交道。而操作系统作为硬件的管理者。因此,为了让用户能够进行网络通信,操作系统提供了一定要提供网络编程的接口,比如套接字socket
编程 。开发者就可以通过系统调用,编写出各种各样的应用层协议,诸如HTTP
、SMTP
、DNS
等等。
操作系统要管理文件、进程、硬件等等,那它是如何管理网络的?
Linux
中一切皆文件,那么网卡就是文件,所以操作系统只需要通过文件管理那一套来对网络进行管理就行了!
因此,网络操作被抽象成了文件系统的一部分。
- 题外话
在
Linux
中,网络套接字(socket
)是通过文件描述符来管理的。当程序创建一个套接字时,操作系统会返回一个文件描述符,这个文件描述符可以用来读写数据。这个设计使得网络编程的操作与文件I/O
操作非常相似。这个我们在下一篇博客再详谈。
另外,网络与系统也有一些区别:操作系统可以有很多种,但为了确保不同的操作系统之间能够进行通信,所有参与通信的操作系统必须遵循相同的协议栈。例如,TCP/IP
协议栈。即无论使用什么操作系统或硬件,只要遵循这一标准,就可以实现网络通信。这种一致性是全球网络互联互通的基础。
网络通信的本质:贯穿协议栈的过程!!!
-
在发送数据时:应用层的数据通过传输层的接口传递到下层,依次经过网络层和数据链路层,最终通过物理层发送。
-
在接收数据时:物理层接收信号并传递给数据链路层,数据链路层将其传递给网络层,网络层交给传输层,最后到达应用层。
四、网络传输
3.1 同局域网的两台主机通信
首先需要明确的是,同一个局域网内的主机是能够直接进行通信的。就比如说,你要将手机投屏到电脑,当投屏时,则会提示电脑和手机必须要连同一个网络。
但是这种直接通信是要有技术保证的,这种技术保证就叫做局域网协议(数据链路层) ,局域网协议非常多,其中最典型的就是以太网协议。
- 以太网的由来
以太这个名词源于物理学中的以太假说:
19
世纪的物理学家认为光波需要通过一种被称为"以太"的媒介传播。这个假说认为以太是一种充满宇宙的物质,光波在其中传播。后来发现以太并不存在,最终沦为物理学界的笑柄。而我们网络中正是通过 光电信号 传输数据的(光电信号中有光),因此就把该标准称为 以太网,用来向过去的物理学理论致敬。
在同局域网的两台主机的通信过程具体是怎么样的?
在网络协议栈的层状结构中,每一层都要有自己的协议 。因此在信息发送给对方之前 ,一定要先通过网络协议栈进行封装:
- 信息先交给应用层,应用层添加上应用层协议的报头信息,将全部数据再交给传输层。
- 传输层收到报文后,再添加上对应传输层协议的报头信息,并将全部数据继续向网络交付。
- 网络层收到报文后,再添加上对应网络层协议的报头信息,接着将全部数据再交付给链路层。
- 链路层收到报文后,最后再添加上对应链路层协议的报头信息,至此数据封装完毕。
说明:
- 封装 :类比快递。当你准备发快递时,首先你会填写快递单的信息。这个过程类似于网络协议在数据的每一层上添加报头。
- 报文/数据包 :就是整个快递包裹,包括快递单和快递盒。即
报文/数据包 = 报头 + 有效载荷
。另外,不同的协议层对数据包有不同的称谓。- 应用层:通常称之为"消息"或"数据"。
- 传输层:称为"数据段"(在
TCP
中),或"数据报"(在UDP
中)。 - 网络层:称为"数据报"
- 数据链路层:称为"帧"
- 有效载荷 : 指除去当前层的报文中的报头,剩下的就是有效载荷。
数据封装完毕后就可以通过局域网将其发送给对端主机了,而当对端主机收到数据后,对应也需要通过网络协议栈对该数据进行解包与分用:
- 链路层通过网卡收到后,先将数据中对应链路层协议的报头信息提取出来,然后将有效载荷交给网络层。
- 网络层收到后,再将数据中对应网络层协议的报头信息提取出来,然后将有效载荷交给传输层。
- 传输层收到后,再将数据中对应传输层协议的报头信息提取出来,然后将有效载荷交给应用层。
- 应用层收到后,最后将数据中对应应用层协议的报头信息提取出来,至此便完成了数据的解包与分用。
说明:
- 解包:去掉对应每层对应的报头。因为每层只认识自己层的协议报头。
- 分用:每一层的协议有很多,而分用的作用就是将数据包正确交付给上层的协议。
也就是说,任何一台主机在发送数据之前,该数据都要先自顶向下贯穿协议栈来完成数据的封装,在这个过程中,每一层协议都会添加上对应的报头信息;而任何一台主机收到数据后,都要先自底向上贯穿协议栈来完成数据的解包与分用。即通信的过程本质就是不断的封装和解包的过程。
协议的共性
- 几乎任何层的协议,都要提供将报头和有效载荷分离的能力。
- 几乎任何层的协议,都要在报头中提供将自己的有效载荷交付给上层的那一个协议。
3.2 局域网/以太网通信原理
我们先将一个故事~
上课铃声响了,老师进来就立马叫张三站起来,并直接问到:"张三,你的作业为什么没交?",此时全班的同学都听到了老师的声音,但除了张三以外的其他同学听到后发现叫的不是自己,于是选择无视。当张三听到老师在叫自己名字后,张三就站起来了,于是开始分析老师传达的信息:为什么没交作业?张三想了半天,想出一个理由:作业我写了,但在家里忘带了,明天带给你,其他同学听到张三的发言依旧选择无视...
故事结束,在上面的故事中,张三所处的环境正是一个 局域网,同学和老师们可以直接通信,但任何时刻,都只允许一人通信,其中每个人的名字可以看作自己的 标识符,老师发出的信息中只包含了 张三这个标识符,因为在一个教室里,所有除张三外的其他同学也能收到老师发出的信息,但他们选择无视,因为 张三这个标识符与自己对不上,当张三与老师在进行对话时,虽然全班人都能听到,但本质上只有张三与王老师在进行通信,而这就是 局域网 中 以太网 的通信原理。
MAC
地址(媒体访问控制地址)是每个网卡的唯一硬件标识符。它在网络数据链路层起到重要作用,用于在局域网内唯一标识设备。每个MAC
地址是由网卡制造商分配的,确保全球唯一,从而使得数据可以正确地发送到目标设备。
实际当主机A
(发送者)想要将数据发送给主机B
(接收者)时,主机A
会将数据封装成以太网帧,并将目标MAC
地址设置为主机B
的MAC
地址。此时此刻,该局域网内的所有主机都收到了该数据,所有主机通过识别自身的MAC
地址,发现该数据并不是发给自己的,那么就把收到的报文丢弃(数据链路层做的)。只有主机B
发现是发给自己的,然后开始解包交付给上一层...
抓包
当你收到不是发给你的数据包时,不是选择无视,而是将其收集了起来,这就是抓包。这就是生活中的吃瓜群众。网卡默认会过滤掉不属于自己的数据包(正常模式),可以手动设置成混杂模式,以关闭过滤。那么就会出现安全隐私问题,但不用担心,因为数据是从应用层开始封装的,那么可以在应用层进行个性化加密。
碰撞
当主机A
在向主机B
发送数据时,有可能主机B
在和其他主机通信。
当同一个局域网中的所有主机都在通信时,由于使用的都是一个共同的通信信道,这就意味着在同一时间,多个主机的通信可能会导致数据冲突和干扰。这种现象在以太网中称为"碰撞"。而发生碰撞的区域就叫碰撞域。就比如说,在同一时刻,你叫张三过来帮忙,我也叫张三过来帮忙,那么张三到底去哪?
所以,想做坏事很简单,在局域网中不断发送大量垃圾信息,增加碰撞的概率,从而影响网络的正常使用。这种行为被称为"网络风暴"或"网络拥堵攻击",它会导致网络性能严重下降,甚至完全瘫痪。
这就也解释了大部分学校的校园网在晚上打游戏的时候会很卡,因为大家处于同一个局域网中,大家都在打游戏,都在发送数据包,容易发生数据碰撞,从而导致数据 延迟递达,也就是网卡。
如何判断发送出去的数据是否发生了碰撞?
因为发送到局域网当中的数据是所有主机都能够收到的,因此当一个主机将数据发送出去后,该主机本身也是能够收到这个数据的。当该主机收到该数据后就可以将其与之前发送出去的数据进行对比,如果发现收到的数据与之前发送出去的数据不相同,则说明在发送过程中发生了碰撞。
也就是说,主机实际是能够通过某种方式,知道曾经发送出去的数据是否发生了碰撞的。
发生碰撞后是如何处理的?
当一个主机发现自己发送出去的数据产生了碰撞,此时该主机就要执行"碰撞避免"算法。"碰撞避免"算法实际很简单:当一个主机发送出去的数据产生了碰撞,那么发送方主机可以选择等一段时间后,再重新发送该数据。这就像现实生活中的两个人同时想要说话,此时对方就都会说"你先说吧",这实际上就是一种碰撞避免。
需要注意的是,实际在网络通信压力不大的时候发生碰撞的概率是不大的,我们不要太小瞧计算机的处理速度,也不要太小瞧网线传播数据的速度。
值得一提的是,我们也可以使用交换机来划分碰撞域,以此减少碰撞的概率。
如何看待局域网
在局域网中进行通信时,任何主机都可以向局域网内发生消息,但任何时刻内,只允许一台主机向局域网中发送信息。否则容易发生碰撞。那么局域网不就是所有主机的共享资源,但它的保障策略不是通过加锁来完成的,而是通过"碰撞避免"算法。
3.3 跨网络的两台主机通信
上面说的都是同一局域网内的主机之间的通信,那不同局域网的两台主机之间的通信过程是怎么样的呢?
路由器
路由器主要工作在网络层,但它也具备数据链路层、物理层 的工作能力。并且路由器也可以看作一台 主机(节点),充当了连接两个或多个局域网的桥梁,负责转发数据包。因此,路由器可以和不同局域网内的任意一台主机进行直接通信。
阐述跨网络的两台主机数据转发的过程
假设主机A
与所在子网标准为以太网,主机B
所在子网标准为令牌环。
- 说明:令牌环是局域网中实现通信的另一种方法,存在一个 令牌,该局域网中的主机轮流持有,只有持有令牌的主机才能发出信息,其目的也是确保任何时刻都只有一台主机发送信息。
主机A
正常将信息封装完毕后,通过MAC
地址发送给对方主机,因为目标主机不在当前局域网,按照之前的逻辑,主机A
发送的数据包会被所有人丢弃,其中就包括路由器。
那刚刚不是说路由器是两个局域网之间的桥梁,负责跨局域网主机的数据转发。
所以光靠MAC
地址是无法完成跨网络通信的,还需要IP
地址。
路由器其实是通过IP
地址来确定数据的转发方向的,因特网上的每台计算机都有一个唯一的IP
地址。而发送方封装数据包时,在网络层封装的报头当中就会包含两个字段,分别是源IP
地址和目的IP
地址。
最后详细过程如下:
- 当发生方将信息封装好后,得知源
IP
和目标IP
不在同一个子网,即是跨网络通信,于是就重新封装以太网报头(更改成路由器的MAC
地址),那么发送方就会把数据包发送给路由器。 - 而路由器处在网络层即上层,它拿到数据包后要进行解包,即将以太网报头拆掉,然后分析
IP
报头中的目标IP
地址,随后根据目标IP
地址查找路由表,决定数据包的下一跳路径。 - 得知需要将此数据包交给 主机
B
,而此时数据包还在网络层,路由器还要将数据包重新封装在适合目标网络的协议帧中。如果目标网络使用的是令牌环网络,路由器会在数据包外部加上令牌环报头。 - 数据包经过封装后,路由器将其丢入令牌环网络中,等待目标主机
B
接收并处理。 - 目标主机
B
收到后,就是解包与分用的过程了。
注意:路由器等中间设备也需要具备封装和解包能力。因为要让数据包适应目标网络的协议,需要将协议报头去除和封装。
屏蔽底层的差异
IP
地址的存在除了帮助数据路由(数据包从源主机到达目标主机的路径选择过程)以外,还有一个很重要的作用,那就是屏蔽了底层网络的差异。
对于通信主机双方的IP
层及其往上的协议来说,它们并不需要关心底层采用的是以太网还是令牌环网,只要在封装的过程中填写源IP
地址和目的IP
地址后,通过路由器进行"变装"后,都能将数据发送出去,因此现在主流的网络也叫做IP
网络。
IP
地址 + 路由器这种优秀的设计使网络在普及时可以畅通无阻。
这种类似的技术还有:
- 虚拟地址空间: 屏蔽了内存之间的差别,让所有的进程看到的都是同一块内存,并且这块内存的布局都是一样的。
- 一切皆文件: 通过文件结构体和函数指针的方案,让我们能够以对待文件的方式对待某些资源。
五、网络地址
5.1 IP地址
当计算机连接到互联网时,它通常会被分配一个唯一的公共IP
地址。这种IP
地址在全球范围内是唯一的,用于在互联网中标识和定位计算机 。目前的IP
地址有两种:IPv4
、IPv6
。注意:凡是没有特殊说明的,IP
地址都是指IPv4
。
IPv4
地址由32
位二进制数构成,为了方便记忆和输入,将每8
个二进制数分为一组,再转换为十进制,变成常用的4
组0~25
5数字的样子,比如192.168.01
。
理论上可以提供2^32≈42.28
亿个IP
地址,但是由于一些地址有特殊用途,所以被保留下来,不允许被大众所使用,那最后真正可用的IP地址只有36.47
亿个,而现在全世界大约有75
亿人,就算这75
亿人只有四分之一的人会接入互联网,那也有18
亿人,而每个人的设备数量可不止一个,比如说我就有一个笔记本电脑、手机、ipad
,如果我向要每个设备都有自己独立的IP
,那我就需要有3
个IP
地址,如果每个人都这样做的话,现有的IPv4
就已经完全不够用了。
自2011
年底,打包分配的IPv4
就已经枯竭了,2020
年底,亚太互联网信息中心将发布不出来一个新的地址,除非有人返还旧的地址,我们很难做到让每个设备都拥有自己独立的IP
地址。因此,我们引入了一项新的技术:网络地址转换NAT
。
如果计算机直接连接到互联网,它将拥有一个唯一的公共IP
地址。假设5
台电脑A
、B
、C
、D
接入了一个路由器,这5
台电脑的IP
地址分别为192.168.0.1
到192.168.0.5
,路由器接入广域网的IP
为6.6.6.6
一般咱们家用来讲,由于路由器是接入广域网并执行网络地址转换的,所以路由器就是你的网关。
假设电脑A
要访问广域网上一个IP
为8.8.8.8
的设备,那数据包从A
出来以后,到达IP
为6.6.6.6
的网关,网关发现这个数据包是去往8.8.8.8
的,就会把192.168.0.1
发送过来的数据的IP
映射成6.6.6.6
,同理的,192.168.0.2到192.168.0.5的电脑发送出去的数据包都可以通过NAT
,把原有的IP
转化成6.6.6.6
,以这个IP
去传输数据给8.8.8.8
,从而实现5
台设备共用一个IP
的效果。
那同理,8.8.8.8
那边如果作为网关,下面还有附属其他的设备,它通用可以挂载很多台电脑,公共8.8.8.8
这一个IP
。
但是这样就存在一个问题,这五台电脑都是走着一个IP
出入的,数据发送出去后,接收方并不知道是哪台电脑发送过来的,接收方下面如果也有很多其他的附属设备,它也不知道这个数据包需要发送给谁,所以这里就映入一个新的概念:端口映射。
我们在IP
地址后面以冒号分割如:6.6.6.6:1000
。网关会以不同的端口号去和外网交互,然后把这些端口映射给局域网内的每一个设备,传输数据的时候,除了IP
地址的映射之外,再额外加上端口号的映射,这样就可以实现共同一个IP
还能精准传送数据了。
在NAT
和端口映射的技术加持下,才让数量完全不够用的IPv4
苟延残喘的坚持这么多年。
如果你理解了上面这些东西,那么现在你听的公网IP
和私有IP
就很好理解了,那5
台192.168.0.1
到192.168.0.5
的IP
地址就是寄宿在6.6.6.6
的网关下的私有IP
。网关所拥有的可以直接用来在广域网上交互数据的6.6.6.6
就是公网IP。
-
就比如说你居住在一个名字叫月亮湾的小区, 具体的地址是
15
号楼二单元201
,假设全中国只有一个小区叫月亮湾,那你出去只要说是月亮湾,大家就直接知道在哪里,这种能直接访问的具体地址,能够拿到大层面上去直接使用的地址就是公网IP
。 -
而
15
号楼二单元201
是你在月亮湾小区的具体地址,你在小区内部,也就是局域网内,说你是15
号楼二单元201
大家都知道你住在哪个位置,但是隔壁的小区也可以有15
号楼二单元201
,隔壁城市的小区也有15
号楼二单元201
,如果你填写快递地址就写15
号楼二单元201
而不写月亮湾,那么就不知道送到哪里去了,像这种只能在小区内部使用的IP
就叫做私有IP
。
当然你也可以和你的运营商申请使用公网IP
,这样接入你家的光猫的IP
地址就会变成不需要任何映射和转换,可以直接访问我们所说的外网了。
但是大部分人对于公网IP
是没有任何需求的,但是但凡如果你是要做一些互联网服务,比如开设邮箱服务器、铺网站等都要用到公网IP
。而随着IPv4
的枯竭,公网IP
的申请也越来越困难了,所以为了彻底解决IP
地址不足的问题,IP
协议就进行了更新迭代,从旧版本的IPv4
升级了新版的IPv6
。
IPv6
由8
组四位十六进制数组合而成,理论上可以提供约3.4 * 10^38
个IP
地址,足以为地球上的每一粒沙子标记上它们自己的独立IP
,这数量就完全能够让我们使用很多年了。
但是有一个比较尴尬的点是IPv6
和IPv4
是完全不同的两个协议,这就意味着他们之间不能直接互通,必须要借组其他的设备去做转换和映射,这就导致想要在短时间内彻底用IPv6
取代IPv4
是很困难的。不过随着互联网巨头们(如百度、腾讯等)纷纷使用IPv6
,再加上目前支持IPv4
的设备也在逐渐被IPv6
所取代,可以预测的是IPv4
终究有一天要被埋没在历史的长河里,成为人类发展进程上一课被埋没的璀璨结晶。
说明:我们普通人使用的网络一般都是私有IP
地址网,地址普遍都是 192.168.xxx.xxx
,这种情况下即使你的 IP
暴露,也无法直接定位至你的主机设备
5.2 MAC地址
MAC
地址用来识别数据链路层(主要是局域网协议)中相连的主机(节点)
MAC
地址 用一个 6
字节的整数表示,占 48
比特位,可表示的最大地址数为 百万
亿+
MAC
地址 一般用十六进制数字加上冒号的形式来表示,例如: 08:00:27:03:fb:19
MAC
地址 在网卡出厂时就确定了,不能修改. MAC
地址 通常是唯一的(虚拟机中的 MAC
地址 不是真实的 MAC
地址 ,可能会冲突,也有些网卡支持用户配置 MAC
地址)
IP
地址很紧张,MAC
地址就不一样,作为数据包转发的节点,同一个局域网内,MAC
地址重复的可能性几乎为0
,48
比特位显得有点浪费,这就好比你每个月要1000
生活费,但你爸每个月都给你1000w
,足够用,但过于夸张了
5.3 IP与MAC的关系
IP
地址 与 MAC
地址 最大的区别在于:传输过程中,IP
地址不会改变,MAC
地址会改变,随着传输距离的增加,MAC
地址改变的次数也会增加
如何理解 IP
地址 与 MAC
地址 的关系?
IP
地址 分为 源IP
地址 、目标IP
地址 ,MAC
地址 也分为 源MAC
地址 、目标MAC
地址
假设有一天,张三考上了大学,临近上学日,一向谨慎的张三选择规划好自己的报名路线
因为张三家住贵州,而他的学校在湖北,途径多个省份,张三需要坐高铁从贵州到重庆,再从重庆到湖北,分为两程:贵州->重庆,重庆->湖北,虽然中途涉及换乘,并且每一程的始发地和目的地也不一样,但张三的最终目的地始终没有改变
- 源IP地址:张三家
- 目标IP地址:张三考上的学校
- 源MAC地址:[贵州,重庆]
- 目标MAC地址:[重庆,湖北]
张三只需要带够钱,并且明确自己的目的地,就一定能抵达
张三的报名之路类似于数据包在网络中的传输之路,IP
地址始终没有改变,但 MAC
地址可能发生改变 ,当 主机A 将数据包交给路由器时,路由器分析 IP
地址得知需要将数据包转交给 主机B ,于是数据包中的 目的 MAC
地址 会变成 MAC-主机B
,主机B 收到数据包后,经过不断解包分用,主机B 将会收到 主机A 发送的信息
所以 IP
地址 用来表示始发地与目的地,MAC
地址 用来表示途中需要经过的中转区间,通常把 MAC
地址 的改变称为 下一跳 ,就是从一个 子网 跳转到另一个 子网 中
IP
地址 和 MAC
地址 共同协作,确保数据能够从源设备传输到目的设备。IP
地址 提供了端到端的逻辑标识,而 MAC
地址 则在局域网中提供了物理设备之间的唯一标识。这种分层的设计有助于网络的灵活性和可扩展性
如何在
Linux
中查看IP
地址 与MAC
地址?
bash
# 查看当前主机所对应的网卡信息
ifconfig
我们用到的大部分局域网都是以太网标准,其中ether
对应就有以太的意思,而ether
后面的这个地址就是当前云服务器所对应的MAC
地址。但实际云服务器上的MAC
地址可能不是真正的MAC
地址,该MAC
地址可能模拟出来的。
除此之外,inet
就是IP
地址,不过它是内网IP
地址。内网IP
是指在局域网中分配的IP
地址,它用于在一个局部网络内的设备之间进行通信。这些地址无法从互联网直接访问,因此它们被称为私有IP
地址。
另外,在Windows
操作系统中,你可以使用ipconfig
来查看Mac
地址和IP
地址。