计算机网络
第一章 概述
1.1 信息时代的计算机网络
1.1.1 计算机网络的各类应用
1.1.2 计算机网络带来的负面影响
1.2 因特网概述
1.2.1 网络,互连网(互联网)与因特网
网络[1]: 由若干
互联网[2]:(internet)网络[1:1]通过路由器[3]互连形成,互联网是"
因特网[4]: (Internet)是当今世界上最大的互联网
1.2.2 因特网发展的三个阶段
第一层 ISP[7] 通常被称为因特网主干网,一般都能够覆盖国际性区域范围,并拥有高速链路和交换设备。第一层 ISP 之间直接相连
第二层 ISP 和一些大公司都是第一层 ISP 的用户,通常具有区域性或国家性覆盖,与少数第一层 ISP 相连接
第三层 ISP 又称为本地 ISP ,它们是第二层 ISP 的用户且只拥有本地范围的网络,如一般的校园网企业网,以及住宅用户和无线移动用户,都是第三层 ISP 的用户
1.2.3 因特网的标准化工作
因特网在制定标准上的一个很大的特点是
因特网所有的
1.2.4 因特网的组成
- 边缘部分
由所有连接在因特网上的主机 组成。这部分是用户直接使用 的,用来进行通信 (传送数据,音频或视频)和资源共享 - 核心部分
由大量网络 和连接这些网络的路由器组成。这部分是为边缘部分提供服务 的(提供连通性和交换)
1.3 三种交换方式:电路交换,分组交换和报文交换
- 电路交换
- 电话交换机接通电话线的方式称为电路交换
- 从通信资源的分配角度看,交换就是按照某种方式动态地分配传输线路的资源
- 电路交换的三个步骤:
- 建立连接(分配通信资源)
- 通话(一直占用通信资源)
- 释放连接(归还通信资源)
- 分组交换
- 发送方:构造分组,发送分组
- 路由器:缓存分组,转发分组
- 接收方:接受分组,还原报文
- 报文交换
- 电路交换
- 优点:
- 通信时延小
- 有序传输(数据不会失序)
- 没有冲突(不会争用物理信道)
- 适用范围广(模拟信号和数字信号都能)
- 实时性强
- 控制简单
- 缺点:
- 建立连接时间长
- 线路独占,使用效率低
- 灵活性差
- 难以规格化
- 优点:
- 报文交换
- 优点:
- 无需建立连接
- 动态分配线路
- 提高线路可靠性
- 提高线路利用率
- 提供多目标服务
- 缺点:
- 引起了转发时延
- 需要较大的存储缓存空间
- 需要传输额外信息量
- 优点:
- 分组交换
- 优点:
- 无需建立连接
- 线路利用率高
- 简化了存储管理
- 加速传输
- 减少出错概率和重发数据量
- 缺点:
- 引起了转发时延
- 需要传输额外信息量
- 对于数据报服务,存在失序、丢失或重复分组的问题;对于虚电路服务,存在呼叫建立、数据传输和虚电路释放三个过程
- 优点:
第四章 网络层
4.3 IPv4 地址
4.3.1 IPv4 地址概述
IPv4地址的编址方法经历了如下三个历史阶段
- 分类编址
- 划分子网
- 无分类编址
32比特的 IPv4地址不方便阅读,记录以及输入等,因此 IPv4地址采用
4.3.2 分类编址的IPv4地址
种类 | 固定前缀 | 网络号位数 | 主机号位数 | 功能 |
---|---|---|---|---|
A | 0 | 8 | 24 | |
B | 10 | 16 | 16 | |
C | 110 | 24 | 8 | |
D | 1110 | - | - | 多播地址 |
E | 1111 | - | - | 保留为今后使用 |
只有ABC类地址可分配给网络中的主机或路由器的各接口
网络地址[12]和广播地址[13]不能分配给主机或路由器的各接口
A类地址,B类地址和C类地址
最小网络号 0,保留不指派
第一个可指派的网络号为 1,网络地址为 1.0.0.0
最后一个可指派的网络号为 126,网络地址为 126.0.0.0
最大网络号 127,作为本地环回测试地址[14],不指派
- 最小的本地环回测试地址为127.0.0.1
- 最大的本地环回测试地址为127.255.255.254
可指派的网络数量为 \(2^8 - 2 = 126\)
每个网络中可分配的 IP 地址数量为 \(2^{24} - 2 = 16777214\)
种类 | 最小网络号 | 最小可指派网络号 | 最大可指派网络号 | 最大网络号 | 可指派的网络数 | 网络中可分配的IP数 |
---|---|---|---|---|---|---|
A | 0 | 1 | 126 | 127 | \(2^{8-1}-2=126\) | \(2^{24} - 2 = 16777214\) |
B | 128.0 | 128.0 | 191.255 | 191.255 | \(2^{16-2}=16384\) | \(2^{16} - 2 = 65534\) |
C | 192.0.0 | 192.0.0 | 223.255.255 | 223.255.255 | \(2^{24-3}=2097152\) | \(2^{8} - 2 = 254\) |
4.3.3 划分子网的IPv4地址
32 比特的子网掩码可以表明分类IP地址的主机号部分被借用了几个比特作为子网号 - 子网掩码使用
连续的比特0来对应主机号 - 将划分子网的
IPv4地址 与其相应的子网掩码 进行逻辑与运算 就可得到 IPv4地址所在的网络地址
A类网络: 255.0.0.0
B类网络: 255.255.0.0
C类网络: 255.255.255.0
4.3.4 无分类编址的IPv4地址
划分子网在一定程度上缓解了因特网在发展中遇到的困难,但是数量巨大的C类网因为其地址空间太小并没有得到充分使用,而因特网的IP地址仍在加速消耗,整个IPv4地址空间面临全部耗尽的威胁
CIDR
为此 IEFT[15]提出了采用
1993年,IEFT[15:1]发布了
CIDR[16:3] 使用“
例子
128.14.35.7/20网络前缀占用的比特数量: 20
主机号占用的比特数量: 32 - 20 = 12
CIDR实际上是
我们只要知道 CIDR 地址块中的任何一个地址,就可以知道改地址块的全部细节:
- 地址块的最小地址
- 地址块的最大地址
- 地址块中的地址数量
- 地址块聚合某类网络(A类,B类或C类)的数量
- 地址掩码(也可以继续称为子网掩码)
例子:
给出 128.14.35.7/20的全部细节(最小地址,最大地址,地址数量,聚合C类网,地址掩码)
- 最小地址: 128.14.32.0
- 最大地址: 128.14.47.255
- 地址数量: \(2^{(32 - 20)}\)
- 聚合C类网的数量 \(2^{(32 - 20)} / 2^8\)
- 地址掩码(也可以继续称为子网掩码): 11111111.11111111.11110000.00000000 = 255.255.240.0
路由聚合
一个路由器将与自己直接相连的局域网的信息通告给另一路由器时,会构造聚合地址块[17]来通告
若路由器查表转发分组时发现有多条路由可选,则选择网络前缀最长的那条,这称为
4.3.5 IPv4 地址的应用规划
定长的子网掩码 | 变长的子网掩码 |
---|---|
使用同一个子网掩码来划分子网 | 使用不同的子网掩码来划分子网 |
每个子网所分配的IP地址数量相同,造成IP地址的浪费 | 每个子网所分配的IP地址数量可以不同,尽可能减少对IP地址的浪费 |
网络的IP地址需求 = 主机地址 + 路由器接口地址 + 网络地址 + 广播地址
分配IP地址
分配网络前缀时需要预留特定地址:网络地址[12:1],广播地址[13:1], 路由器接口地址[18]
代码实现分配IP地址
输入格式
第一行是该系统分配到的地址块
第二行是该系统内的局域网数 \(n\)
下面 \(n\) 行是每个局域网的主机数,以及与该局域网直接相连的路由器的数量
代码
该代码实现了对输入分配给系统的IP地址块以及各局域网的主机数以及直接相连的路由器数,自动按照优先分配占用地址多的局域网,优先分配位上数为0的规则,分配每一个局域网包括前缀的地址块的功能
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// 点分十进制的段数
constexpr int m = 4;
// 每一段的位数
constexpr int k = 8;
constexpr int pn = 62;
ll p[pn + 1];
// 初始化 2 的幂次
void initp() {
p[0] = 1;
for (int i = 1; i <= pn; ++ i) p[i] = p[i - 1] * 2ll;
}
// 求出不小于 x 的最小的 2 的幂次(二分算法)
// O(log_2(x)) 对于输入的局域网数 n 该算法为O(1)
ll higherbit(ll x) {
ll l = 2, r = m * k;
while (l <= r) {
ll mid = (l + r) >> 1;
// 减 2 是因为全 0 是网络地址,全 1 是广播地址需要预留
if ((1ll << mid) - 2 < x) {
l = mid + 1;
} else {
r = mid - 1;
}
}
return (1ll << l);
}
// 化为点分十进制
string f(ll ip) {
string res = "";
vector<ll> a(m + 1);
for (int i = m; i >= 1; -- i) {
a[i] = ip % (1 << k);
ip >>= k;
}
for (int i = 1; i <= m; ++ i) {
if (res.size()) res += '.';
res += to_string(a[i]);
}
return res;
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
initp();
ll prefix, ip = 0, n;
char c;
vector<ll> t(m + 1);
for (int i = 1; i <= m; ++ i) {
cin >> t[i] >> c;
ip <<= k;
ip += t[i];
}
cin >> prefix;
cin >> n;
vector<ll> LAN(n + 1); // 每个局域网中主机的数量
vector<ll> routers(n + 1); // 每个局域网直接相连的路由器的数量
vector<string> ans(n + 1); // 每个局域网对应的网络前缀
vector<tuple<ll, ll, int, int>> tl;
vector<ll> IP(n + 1);
vector<string> pre(n + 1);
for (int i = 1; i <= n; ++ i) cin >> LAN[i] >> routers[i];
for (int i = 1; i <= n; ++ i) {
tl.emplace_back(
higherbit(LAN[i] + routers[i]),
LAN[i] + routers[i],
-i,
i
);
}
// 按局域网内的主机数降序排序
sort(tl.rbegin(), tl.rend());
for (auto [num, rnum, _id, id] : tl) {
// 计算地址块
string cur = f(ip);
// 计算前缀
int cn = prefix;
while (num < p[m * k - cn]) cn++;
// 合并成答案
ans[id] = cur + "/" + to_string(cn);
// 存储当前IP和前缀用于后续验证答案
IP[id] = ip;
pre[id] = cn;
// 模拟占用这些地址号
ip += num;
}
for (int i = 1; i <= n; ++ i) {
cout << "LAN" << i << ": " << ans[i] << "\n";
}
auto show = [&](int id) {
ll x = IP[id];
vector<int> c(m * k);
for (int i = m * k; i >= 1; -- i) {
c[i] = x & 1;
x >>= 1;
}
for (int i = 1; i <= m * k; ++ i) {
cout << c[i];
if (i % k == 0) {
if (i < m * k) cout << ".";
else cout << "\n";
}
}
};
// 输出二进制形式,人工手动验证答案
// for (int i = 1; i <= n; ++ i) {
// cout << "LAN" << i << ":\n";
// show(i);
// }
}
4.4
联系我
博客失去时效性或有任何不详尽的可联系我
QQ: 2832640093
路由器 NEED ↩︎
ARPANET 第一个分组交换网 ↩︎
NSFNET 国家科学基金网 ↩︎
ISP (internet service provider)互联网服务提供商 ↩︎
ISOC 因特网协会,是一个国际性组织,它负责对因特网进行全面管理,以及在世界范围内促进其发展和使用 ↩︎
IPv4地址 就是给因特网[4:2]上的
每一台主机(或路由器)的每一个接口 分配一个在全世界范围内是唯一的32比特的标识符 ↩︎点分十进制表示方法 每8位分为一组,写出每组的十进制数,每个十进制之间用"."来分隔 ↩︎
本地环回测试地址 NEED ↩︎
聚合地址块 将与该路由器直接相连的局域网的的IP取共同前缀其他位变0后生成的地址块 ↩︎
路由器接口地址 每个路由器的接口需要预留独立的IP地址 ↩︎