文章目录
- 1. 应用层
- 自定义协议
- 通用的应用层协议
- (1) xml
- (2) json
- (3)protobuffer
- 2.传输层
- UDP协议
- TCP协议(灰常重要!!!!!)
- 1. 确认应答
- 2. 超时重传
- 3. 建立/断开 连接 : 三次握手/四次挥手
- 4.滑动窗口
- 5.流量控制
- 6.拥塞控制
- 7.延时应答
- 8.捎带应答
- 9.面向字节流
- 10. 异常情况
- 3.网络层IP协议
- IP协议报头
- 如何解决32位IPV4不够使用
- 网络管理
- 4.数据链路层
- 以太网
- 5.物理层
网络通信是经过协议来传输的,遵守协议确保了双方的信息能够互相传递,同时也对硬件设备做出了统一约束.
以下详细介绍网络分层系统以及各个层级的协议:
1. 应用层
应用层即对应着应用程序,是面向程序员最直接的层级,程序猿通过调用系统封装的网络API来编写代码.
自定义协议
应用层中有很多的现成协议, 但是更多情况是根据实际的业务场景来自定义协议
- 什么是自定义协议?
开发应用通常是多个程序员合作, 像前端程序员和后端程序员之间搭建网络传输就需要协商好定下一个协议 - 怎么自定义协议?
自定义协议其实非常简单, 网络传输本就是在传送字符串, 一个字符串数据里面包含的是什么数据? 数据与数据之间使用什么符号分割? 什么符号表示这一条数据已经结束符号后面是下一条数据的内容…这些都可以由程序猿之间约定好
通用的应用层协议
由于应用层的协议多样化,可能导致公司与另一个公司之间每次想要合作都需要自己生成一种协议, 聪明的程序猿之间为了更方便的约定协议,定下了几种通用的方案
(1) xml
大致形式如下: 以开始标签和结束标签夹住内容,以类,对象,属性等层级信息记录
<?xml version="1.0" encoding="UTF-8"?><!-- 图书目录示例 --><bookstore><bookid="B001"category="fiction"><titlelang="zh">三体</title><author>刘慈欣</author><year>2008</year><price>45.00</price><description>地球文明与三体文明的宇宙博弈</description></book><bookid="B002"category="non-fiction"><titlelang="en">Deep Learning</title><author>Ian Goodfellow</author><year>2016</year><price>320.00</price></book></bookstore>xml 的优点
- 数据可读性高,一眼就可以看出来数据是什么
- 清晰看出开始地和结束地
- 数据插入对其他数据无影响,只需要插入标签即可
xml 的缺点
- 标签的占据比数据内容还多
- 冗杂的标签会降低网络传输效率,消耗更多流量
(2) json
json 的写法更像是一种"赋值"
[{"id":1,"name":"Alice","age":30,"email":"alice@example.com"},{"id":2,"name":"Bob","age":25,"email":"bob@example.com"},]可以采用数据库表格的连接形式来设置json
{"users":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}],"orders":[{"orderId":"O001","userId":1,"product":"Laptop"},{"orderId":"O002","userId":2,"product":"Phone"}]}对比与xml , json 的可读性也很高,扩展性也强, 省去了部分无用标签,但是还是会有标签浪费的情况
(3)protobuffer
在开发者开发时, 定义这个字段的数据是什么含义
当进行传输时,不会传入这些含义,只传输数据对应的二进制
优点: 传输效率最快
缺点: 最难人工阅读
2.传输层
传输层虽然已经实现好并且提供socket等api供我们使用,但是了解传输层机制是工作中非常重要的内容,同时也是很经典的面试题
- 传输层最常见的两个协议,一个是UDP协议,一个是TCP协议,各有各自的优点.
- 传输层由报头和载荷构成,报头负责带路将应用层数据打包带走
UDP协议
| 特点 | 解释 |
|---|---|
| 无连接 | 全程没有双方互相建立连接 |
| 不可靠传输 | 无法确认数据有没有被对方收到 |
| 面向数据报 | 以数据报为单位进行传输 |
| 全双工 | 数据可以双向传输 |
了解协议报头:
UDP报头分为四个部分
16位源端口 (最多表示2字节大小端口)
16位目的端口 (最多表示2字节大小端口)
16位UDP长度(表示的是整个数据报的长度,最大只有2字节)
- 2字节表示数据长度,单位为’字节’.意味着整个UDP最大也就是64kb,64kb在当今大数据时期是非常小的,为什么不对UDP容量进行扩容呢?
其实扩容是非常简单的,只不过由于协议的特殊性,每一台机器,每一台设备都定下了UDP最大长度就是这么多,如果一个公司擅自将UDP最大长度改大,后果就是这个公司所有的设备都不能与外界互通. - 那么为什么不全球一起改变呢?
说的简单做的难! 改协议就要停设备,网络每秒钟都有人使用,每一秒的暂停对经济损失都是不可想象的,没有人会愿意当这种小白鼠.
- 2字节表示数据长度,单位为’字节’.意味着整个UDP最大也就是64kb,64kb在当今大数据时期是非常小的,为什么不对UDP容量进行扩容呢?
16位UDP校验和(用于判断在传输的过程中,数据有没有被更改或消失)
网络信号以电信号,光信号,电磁波等等方式传播,传播的过程中难免会有数据丢失,校验和可以判断当前数据是错误的,但是不能判断当前数据是正确的校验和只有2字节,是怎么实现记录的?
首先,将整个数据报分段(包括报头),然后,将所有分段的数据全部加起来,若超出范围就加在末尾: 比如 1,2000 => 2001 最后取反数据.
当接收方收到数据报, 就会重新算一遍,如果校验值不相同,则直接丢包.避免无意义的乱传.另外,当今网络较为发达,多个信号同时丢失导致校验值和之前一样的概率比较低.
TCP协议(灰常重要!!!)
| 特点 | 解释 |
|---|---|
| 有连接 | 全程双方互相建立连接(通电话聊天) |
| 可靠传输 | 可以确认数据有没有被对方收到 |
| 面向字节流 | 数据传输可抽象成流的形式 |
| 全双工 | 数据可以双向传输 |
了解协议报头:
TCP 的Data Offset(首部长度) 字段为 4 位,表示头部长度的 32-bit 字数(最小值 5 → 20 字节,最大值 15 → 60 字节)。4位的范围0~15 单位不是1字节 而是4字节. 因此TCP最大报头为15 * 4 = 60字节.
- 在报头中可以分2部分,前五行各种属性占据20字节(固定20字节),选项可有可无,最大40字节
- TCP报头 同样存储着2字节的源端口号和目的端口号
- 得知UDP固定长度吃了亏,TCP对报头长度做了个心眼,预留6位,现在先不使用,等到不够的时候,就可以用上
- 6位标志位,是TCP的非常核心的部分,它们每一位由 0 或 1 构成, 代表着这次信号是否具有某些性质
- 与UDP类似,TCP 也有报头和载荷一起计算的校验和
详细介绍TCP传输机制,列举个别较为重要的特性
1. 确认应答
TCP 最重要的就是可靠传输这一特性, 你怎么知道对方收没收到信息,怎么实现可靠传输? 答案很简单,让对面给你回复说: "我收到你的消息啦!"就可以了
给出一个简化版本
然而实际网络传输中,往往会出现"后发先至"的情况, 这是因为传输的过程要经过诸多硬件设备,走的路就很可能不一样,还有可能被硬件设备阻塞等待. 这样每次确认应答就会显得杂乱无章
针对这样情况, TCP确认应答是这样做的:
ACK标志位,当ACK标志位1时,代表着这一次传输为确认应答,表示的意义为" 收到 ! ".
在报头中每次传输列出序号,TCP是面向字节流的,因此一个字节占据一个序号值,例如:
① A -> B (ACK = 0)
“你好啊,你在干嘛呀,做我女朋友吧!” 假如载荷数据为100字节
整个数据报长度会在IP协议(下一层协议)记录总长度(IP协议存储) = 报头长度(存在报头) + 载荷长度(没有实际存储长度,通过计算得到)
② B -> A (ACK = 1)
③ B -> A (ACK = 0)
“下头男,gun!” 假设这里载荷也是100字节
④ A -> B (ACK = 1)
需要注意的是 确认应答的时候, 只发送报头,因为这时并没有任何载荷发送,
因此这次序号虽延续了上次的值,但是并没有真的占据这个值.
TCP 确认应答,是可靠性传输和核心机制\
2. 超时重传
当路途的某个服务器负载量太大,出现"堵车",校验和可能收到物理因素出错
网络传输过程错综复杂, 数据传输或者是应答被损坏或丢失称为"丢包"
那么这两种情况发生丢包该怎么办呢?
- 数据丢包
如果长时间没有收到对方回复(存在一个时间阈值),就再发一次.
- 超时重传也不是无限次重传的,达到一定的次数之后,就会重置连接.如果重置连接也失败,那就放弃连接(挂断电话)
- 重传的时间阈值也不是固定不变的,会根据重传的次数变化
应答ack丢包
ACK 丢失了, 发送方没等到应答,也会以为是自己的问题,就会触发超时重传
如果这种情况没有处理,就有可能会出现一个逻辑两次执行的情况,这是严重错误!
事实上缓存区可以解决这种情况网络传输收到的数据是存放在缓冲区当中的, 如果放在缓存区的数据还没有被应用层read走,缓存区会检查收到的数据,已经收到过的,那就把它丢弃.那如果缓存区的数据已经被read到应用层了,又收到了一遍呢?
应用层读取缓存区的数据,一定是按照从小到大的顺序读取的,socket API 会记录当前已读数据,从未读数据继续往下读取,如果收到了之前已读的序号,就会认为是重复的包,直接丢弃
3. 建立/断开 连接 : 三次握手/四次挥手
三次握手:
TCP 为有连接传输,也就是每次传输都能知道双方的信息,建立连接的过程我们称为"三次握手"
三次握手的发起者一定是客户端发起的,不可能说服务器主动跟你建立连接
- 客户端发起syn(同步报文段) 这个同步报文与 单纯的ack类似,都是只有一个报头,此时SYN标志位为1,表示的意思就是"我想和你连接"同时,也在告诉你我是谁.
- 服务器看到请求, 作为可靠传输,要先 ack :“我收到了这次请求”
- 服务器也要向客户端发送SYN连接请求
- 客户端 ack 回应
当然,四个步骤称为三次握手是因为中间两部分实际上是可以合并同时发送 ack + syn
为什么服务器收到了客户端的第一次SYN之后, 还要再与客户端SYN一次?
- TCP是全双工的,第一次客户端SYN初始化了序号,告诉服务器序号从这里开始计算, 服务器也要告诉客户端我这边的序号从哪里开始计算
- 双方都发送,一方面是检测物理层传输是否通畅,另一方面也是检测双方的发送和接收功能是否正常.
总结: 三次握手实际上是四次交互; 少于三次握手, 双方不能连接成功. 多余三次握手,则是没有必要的浪费
不顺利的三次握手: 网络传输常有"后发先至"情况,如果每次三次握手开始的序号都相同,就有可能发生以下情况
迟来的数据给到了下一次连接,这当然不行!
TCP背后还有序号分配的策略. 让这一次的连接与之前的连接开始序号大程度不同, 避免清朝的剑斩到现代的官
四次挥手:
TCP作为全双工协议,断开连接也需要双方分别确认四次挥手的发起者可以是客户端也可以是服务器。
连接的本质上就是用一些数据结构,来存储对方的信息, 断开连接,就是要从这些数据结构删除连接信息.
四次挥手与三次握手类似,通过标志位FIN通信,也是进行四次交互
四次挥手就不能将中间两次合并吗?
三次挥手syn 和 ack 都是内核实现的
四次挥手有时候能和并. 如果当 ACK 和 FIN 几乎同时进行的时候就可以进行合并, 但实际上,服务器FIN主要取决于应用层的代码实现而 ACK 是系统内核决定的,是非常快执行的
调用socket.close()关闭SOCKET,如果SOCKET关闭的慢,就不合并. SOCKET关闭的快,就可以进行合并
为什么要进行四次?
- fin 并不是断开连接的立即执行指令,实际意义上是告诉对方"我要说的话已经全部说完了" ,假设是A发起fin
- B 收到 返回ack告诉A “这个fin没有丢包,我已经知道了”
- 虽然A的话说完了,但是B还可能有话要说啊,
- 发送方说完了话,不代表接收方的话就说完了,可能接收方还需要发送,所以需要双方都决定全部的交流都完成了,再断开连接
三次握手与四次挥手异同:
相同性:
本质上都是4次交互,中间两次交互都是同一台机器.
都是由 syn/fin -> ack -> syn/fin -> ack 这样的形式建立连接或者断开连接的不同性:
发起者不同,三次挥手一定是客户端发起,四次挥手既可能是客户端也可能是服务器
三次握手中间两次会合并,而四次挥手既有可能合并也可能不合并
与线程类似,TCP在’‘三次握手,四次挥手’'前后都有状态:
TCP 中的状态也会保存在数据结构当中,明确了状态就能明确当前在做什么或者未来应该做什么.
这么看状态转换图相当复杂,我用表格和步骤来讲解
| 状态类型 | 状态名称 |
|---|---|
| 初始 | CLOSED |
| 监听 | LISTEN |
| 建立中 | SYN_SENT |
| 建立中 | SYN_RECEIVED |
| 通信中 | ESTABLISHED |
| 主动关闭 | FIN_WAIT_1 |
| 主动关闭 | FIN_WAIT_2 |
| 被动关闭 | CLOSE_WAIT |
| 被动关闭 | LAST_ACK |
| 等待安全关闭 | TIME_WAIT |
| 最终 | CLOSED |
三次握手状态转换:
- 程序还没调用connect()时默认就是
close初始状态, 当服务器启动 从close转变为listen状态,表示现在已经可以接收请求了 - 客户端主动发出请求, 变成
syn_sent状态 , 服务器收到请求,变为syn_received意思是我收到请求了, 准备返回syn+ack - 然后客户端收到ack,客户端单方已经成功建立连接,变成
established"连接状态" , 随后返回ack,告诉服务器成功收到, 服务器也成established"连接状态".
四次挥手状态转换:
TCP是全双工传输,正常情况下,.不能一方想断开就直接断开,需要双方都确认好
- 假设A方是主动发起断开者, A发送fin告诉 B “我没什么可说的了” ->转为
fin_wait_1状态, B 收到 A 的fin,得知 A 不想再说话了, 先告诉A(ack):“收到!”, B 转换成close_wait等待自身的话全部说完. A 收到ack, 表示A已经得知, B知道A不再说话了,转换成fin_wait_2状态,此时A在等待B不再说话 - B在
close_wait状态时,只是得知A不再说话,B任然有可能还有话要说,也就是第二次挥手与第三次挥手之间任然可能有 B 对 A 的单向传输, A可以正常返回ack. - 当 B 把所有话传输完, 进行第三次挥手,发送fin并且转换成
last_ack状态,表示B的话也说完了,如果A收到了就可以关闭连接了. - A 收到 B 的fin; 得知 B 已经把全部话说完了,返回ack表示收到, 这时A好像已经可以
close了.但是,如果这时候断开,ack又刚好丢包了, B 超时重传, A又收不到,此时就是异常断开了, 所以为了能够防止再次收到B 的超时重传, A 会再待一会,也就是time_wait状态 - B 收到最后的ack后,可以直接
closed断连了,因为已经不需要其他的交互了.(所谓的断连,是在数据结构中删除对应的通信数据). A 在 2MSL (MSL是报文的生存单位时间,一个MSL大概在一两分钟) 之内确保没有收到 B 的超时重传, A 断开 进入closed
以上就是"三次握手,四次挥手的"的状态转换过程. 状态的转换需要熟悉三次握手和四次挥手的流程.
TCP为了实现可靠性传输必然会降低传输速率,这是不可能的避免的代价, 以下介绍TCP优化传输效率的特点:
4.滑动窗口
当有大量的数据需要传输时应当进行快传.
如果传输是按一个数据报一个数据报传的,那么传输效率会大大浪费在ack上
那滑动窗口是怎么批量传输的同时还能保证可靠性的?
在传输阶段,传输的数量增长到窗口大小时,每次收到一个ack,窗口就可以平移发送下一次传输(未发生丢包情况下,即便是ack返回的顺序不一样,只要窗口还有空余,都可以发送下一段数据报)
丢包情况:
ack丢包
这时候只要不是最后一条ack丢包, 都完全不必理会,因为后面的ack同样会告诉你:“我下一次想要5001开头的数据”.意思就是5000之前的数据我都收到了.2.数据报丢包
确认应答序号永远是告诉对方,“我下一个希望收到什么序号”,即便是收到了1001-2000 和 3001-4000的内容, 2001-3000内容丢失,也还是告诉对方:“我下一个要2001开头的数据”. 那后面的数据怎么办?后面的数据会存在缓存区中, 接收方就可以不断的告诉发送方:“我要2001开头的数据”
一开始接收方收到ack确认应答为2001,不以为然,认为是传输过程太慢,还没有传送到,当接收方持续收到需要2001开头的数据之后(>=3次)它就知道是数据报丢包了,进行重传.
当接收方收到2001开头的数据后,它就可以根据缓存区快速的跳到最后收到的序号,发送最大的应答序号
超时重传和快速重传之间并不矛盾,快传更容易在大量数据快速传递时触发
5.流量控制
滑动窗口虽好用,但是也不可能一直增大,那么是什么来控制滑动窗口的大小?
控制窗口大小,需要结合接收方的缓存区剩余空间大小,在报头中有"16位窗口大小这个属性". 接收方会将自己的剩余缓存空间大小放在里面,告诉发送方你可以调整的窗口大小为多少.
窗口大小也并非只有64KB的大小,选项中可以设置有窗口拓展因子,扩展因子设置为1,就相当于 64KB * 2^1;
如果缓存区空间为0,发送方停止发送,之后发送方会发送只有报头的一种"试探性"包,来试探是否可以继续发送.
6.拥塞控制
此优化考虑的是传输路径上设备偶尔爆满/堵塞情况,但实际上我们很难得知传输过程什么时候通畅,什么时候堵塞,它是动态变化的.
这就会和窗口大小引起冲突, 即便对方缓存区空间大, 但在传输路径上堵塞丢包,窗口太大就显得不合适.于是窗口的大小还需考虑传输路径是否通畅,窗口的取值为二者取最小.
由于无法得知路径设备上的具体传输量,TCP以动态应对动态,通过不断的变化,找到较合适的窗口大小.
- 慢启动,刚开始传输的时候,传输速率很小,保证一开始不拥堵
- 未出现丢包的情况,说明道路通畅,开始指数增长,到达了一定的阈值之后,开始线性增长.(阈值通常由首次丢包而改变)
- 线性增长窗口持续增大,直到出现丢包,出现丢包后,更新阈值,(出现丢包时窗口大小的一半),然后再从阈值线性增长.
7.延时应答
也是在优化滑动窗口
接收方在收到数据之后,不会立即返回ack(此过程由内核调用),会等个几十或几百毫秒.
在这等待的时间中, 一个是能让接收方处理掉数据,增加缓存空间增大窗口大小,还有就是数据还在传输的路径上,等待一下就可以收到更多的数据,一次性返回一个序号更大的ack.
8.捎带应答
基于延时应答, 如果返回ack的同时,还有内容发送,就可以一并发送.
ack是内核触发的,而数据是代码处理的,时机可能同也可能不同.
9.面向字节流
字节流的一大问题就是粘包问题,不好处理边界问题. UDP以数据报为一个单位,没有这类问题,但TCP是面向字节流的,需要程序员明确包与包之间的边界.
常见的分隔方式有:
- 定义分隔符,指定字符分割,程序员之间的约定
- 指定包的长度.在数据的开头就写好了这个数据的长度
- 使用xml,json,protobuffer等应用协议
10. 异常情况
考虑网络突然断联,关机,断电等情况,双方会怎么应对; 如何安全的删除双方的连接数据?
进程崩溃
进程无论是正常关闭还是异常崩溃,虽然进程关闭,回收文件资源,但是TCP连接还存在,都会正常四次挥手.一方关机
其中一方关机时,系统会强制杀死进程,一开始同样是触发四次挥手任务,如果四次挥手执行的快,那就是正常断连.
而如果挥手执行的较慢, 第四次挥手返回ack之前, 不管关机这方收没收到ack和fin,关机这方都删除对应的资源. 如果在第四次挥手没有成功发送ack, 就会多次触发超时重传,多次联系不上, 己方就会单方面释放连接信息.一方断电
(a)断电是接收方
发送方发送数据之后,接收方不返回ack,发送方超时重传多次还是接收不到
这时发送方就会尝试"复位",报头中的RST是复位的标志位,将RST标志位1请求复位(就是清除所有临时数据,只保留关键数据二次连接)
复位失败,则单方释放连接信息.
(b)发送方断连
接收方本身就在等待发送方发送数据, 只不过每隔一段时间,发送方没了动静,接收方就会发送一个心跳包,TCP 本身没有通用的心跳机制(内核有 TCP keepalive,但默认间隔很长)。生产系统常在应用层实现心跳或使用更灵活的探测机制。RST 表示异常终止连接;在真实网络中,不同故障(进程崩溃 / 断电 / 链路中断)会引起不同的内核反应(可能是 RST、长时间重传后超时或资源回收)。
网络断开
这就是中间的道路全断了,感知不到对方的存在,最后也是超时删除链接信息.
以上仅是TCP协议较为明显的特点,常在工作中接触和使用,还有其他特点可了解TCP的RFC官方文档
传输层的应用场景,考虑效率首选UDP,考虑可靠性首选TCP,当然还有其他的协议会拟补它们各自的缺陷,甚至会用UDP来实现TCP的可靠性.
3.网络层IP协议
IP协议报头
IP协议使用一套地址体系,来描述每个设备在互联网上所在的位置.
网络层会将传输层的数据包打包,以IP报头带领传输.
IP协议报头左上角表示的就是当前IP版本,目前只有IPV4和IPV6版本
4位首部长度:和TCP报头一样,报头长度由固定的20字节+选项里的字节,单位是4字节
8位服务类型(type of service),实际上只有4位有效,4位中只有一位为1,其余都是0; 表示当前IP协议所处的工作模式
- 最小延时
- 最大吞吐量
- 最高可靠性
- 最小成本
16位总长度,(总长度 = 报头 + 载荷) 虽然一个IP数据报是64KB限制,但是IP数据报提供了拆包组包的功能,即使TCP数据报大于64KB,也可以分多个IP数据报进行传送. IP协议的拆包是系统内核完成的,拆包大小限制大概率取决于数据链路层包的大小.
- 16位标识代表是否是同一个传输层的数据报,相同则16位标识的值也相同
- 13位片偏移表示拆开之后的先后顺序
- 3位标志, 只有两位有效,其一表示这个IP报是否是拆包,另一个表示结束标记, 看到带有结束标记的这个IP报,代表这一整体传输完了.
8位生存时间TTL,单位为"次数",存储的是一个整数,每经过一个路由器,TTL - 1, 这样可以避免这个数据一直在外流浪不归. TTL 一般在 32 或 64 就足够.
8位协议表示在传输层使用哪个协议
16位首位校验和只对首部校验,载荷部分由传输层的校验和自行校验
32位源IP地址和32位目的地址
如何解决32位IPV4不够使用
上世纪90年代已经在处理这个问题
动态分配,正在使用网络的用户分配IP地址,不在使用网络的用户不分配IP地址.
NAT机制:
- 将IP地址分成两大类
(1) 私网IP / 局域网IP
这类IP 以 10.* || 192.168.* || 172.16 - 172. 31.* 开头
(2) 公网IP / 广域网IP
除了私网IP 其他都是公网IP - 局域网IP可以重复使用, 而公网只能有一个
- 局域网如何访问公网?
- NAT机制集成在路由器当中, 一个一端连接着局域网,另一端连接着广域网的路由器通常有它自己的公网IP,当我们局域网的IP传送给这种路由器,它就帮我们将数据以 这个路由器的公网IP代替发送.
- 路由器会通过数据库那样的大表格,记录着源局域网IP和目的公网IP, 保证双向传输不错乱. 如果多设备访问同一个公网, 就通过端口号(保存在传输层)来区分, 如果端口号也无法区分, NAT 就帮你替换一个虚拟的端口号来做区分.
- NAT(通常在路由器上实现)通过维护内网 IP:port 到公网 IP:port 的映射(状态表)来实现多台内网设备共享一个公网地址
如今网络大多是动态分配和NAT机制相结合
- 将IP地址分成两大类
IPV6从根本上解决问题
IPV6 16个字节表示IP地址, 2^128的天文数字能将地球上的每一粒沙子都标上序号. IPV6毕竟是不同于IPV4的另一种协议,要想全面普及,就需要集体升级设备,这活很耗费资金,但没有实际上的速率提升.
网络管理
- 局域网IP形式采用3字节网络号 + 1字节主机号形式表示; 同一个局域网中的网络号必须得是一样的,局域网内的IP也是路由器帮忙分配好的,当然,也可以手动分配
- 两个相邻的局域网,网络号不允许相同.
- 特殊的IP
- “127.0.0.1” 环回IP,表示自身主机,实际上127.*都是环回IP
- 局域网中的主机号不能为0, 主机号为0的IP代表这一网段.
- 局域网中的主机号全为1(最大取值),代表"广播地址",将数据传送到广播地址相当于将数据发送到全体局域网设备(TCP不支持广播)
4.数据链路层
以太网
数据链路层通过以太网横跨物理层.
以数据帧格式传输
由于历史原因,数据链路层也创建了一套mac地址体系,专门负责数据链路层.
IP地址侧重于整体的转发,而mac地址侧重于局部路径转发.
- 6字节mac地址的容量至今还是足够, mac地址和设备网卡是绑定的
- 传输过程中每经过一个路由器目的mac都会发生改变
数据帧中分3种类型
- 常规的IP数据报
- ARP请求/应答 IP -> mac 又IP传输确认传输方向之后,需要确认下一个设备的mac具体地址
- RARP请求 mac -> IP (不常用)
- IP协议的拆包长度大概率取决于数据帧中的约束长度.
5.物理层
物理层负责比特的实际传输:在物理媒体上把比特流编码成电信号/光信号/电磁波并发送;同时负责接收端的解码、信号同步、比特定时恢复等。上层只看到“比特流”,不关心电平如何变化。