计算机网络学习笔记

  1. 一次输入URL会发生的事
  2. 网络分层的真实含义是什么
  3. ifconfig

一次输入URL会发生的事

浏览器输入URL -> DNS(更精准:HTTPDNS) -> IP地址 -> 浏览器打包请求(HTTP/HTTPS协议)










HTTP头 POST,URL HTTP x.xx 正文格式: json, 正文长度: n
内容 用户要做什么

-> TCP协议或UDP协议














TCP/UDP头 浏览器端口 应用端口
HTTP头 POST,URL HTTP x.xx 正文格式: json, 正文长度: n
内容 用户要做什么

-> IP协议


















IP头 客户端电脑IP 目标服务器IP
TCP/UDP头 浏览器端口 应用端口
HTTP头 POST,URL HTTP x.xx 正文格式: json, 正文长度: n
内容 用户要做什么

知道了IP地址后,要通过IP地址找到目标机器,操作系统通过IP地址判断是在本地还是在远处, 如果是远处,则需要去网关

操作系统启动的时候,会被DHCP协议配置IP地址,以及默认的网关的IP地址 192.168.1.1

-> ARP协议(默认网关的IP地址) -> MAC地址






















MAC头 客户端电脑MAC: 192.168.1.101的MAC 网关的MAC: 192.168.1.1的MAC
IP头 客户端电脑IP 目标服务器IP
TCP/UDP头 浏览器端口 应用端口
HTTP头 POST,URL HTTP x.xx 正文格式: json, 正文长度: n
内容 用户要做什么

网关往往是一个路由器,通过路由表判断到某个IP地址怎么走,跨越网关需要拿出IP头,网关在负责告诉怎么走

网关之间的沟通通过路由协议 常见的有 OSPF, BGP

在一个网关内用内部的MAC地址找到下一个网关, 一直到走出最后一个网关, 最后一个网关通过目标服务器恢复的一个MAC地址找到目标服务器.

目标服务器发现了MAC地址对上了,就取下MAC头,交给操作系统的网络层. IP也对上了,就取下IP头, IP头里会写上一层封装的TCP协议, 交给TCP层.

到了TCP层收到每个包就会回复一个包说明收到了, 这个回复的包的内容是TCP层的一个说明,于用户内容无关,沿着刚才的路径走回去, 报个平安

如果一段时间后没有收到这个包, 发送端的TCP层会重新发送这个包, 直到收到平安到达的回复.这个重试并非用户的动作重新请求,而是用户只发出一次请求, TCP层不断重试, 除非TCP层出了问题,例如连接段了,才会轮到应用层重新发送请求.

当网络包到了TCP层, 通过TCP头的端口号找到目标网站的进程正在监听这个端口号, 将这个包发给网站, 网站进程的到了HTTP请求的内容,知道了用户的需求,然后根据RPC调用相关的进程处理.

处理完成后, 会回复一个HTTPS包, 告知用户操作成功, 沿着来时的路, 经历来时所经历的一切回去.

习题: 当网络包到达一个网关的时候,可以通过路由表得到下一个城关的地址, 直接通过 IP 地址找就可以了, 为什么还要通过本地的 MAC 地址?

答案: IP是网络层使用的, MAC是链路层使用的, IP包最终还是要通过物理链接还有MAC地址进行交互.

网络分层的真实含义是什么

网络为什么要分层: 复杂的程序都要分层,这是程序设计的要求 倘若说整个网络只有一层,网络上所有节点都处于同一层级,必然会造成混乱,所以最主要原因还是要明确职责.这是架构与设计模式的问题.

  1. 当一个网络包从一个网口经过(当前buffer位于目标服务器的链路层), 看到后根据自身策略决定是否拿进来处理一把.

  2. 拿进来后,交给程序处理

    调用 process_layer2(buffer)(伪代码), 这个函数的作用是从 buffer 中摘掉第二层的头,看一看根据头里面的内容有什么操作

    如果发现MAC地址相符, 调用 process_layer3(buffer), 这个时候 buffer 已经没有第二层的头了(上一层处理中拿掉)或者偏移后进行操作, 然后看看这个 buffer 是发送给自己的还是需要自己转发出去的.

    如果 IP 地址不是自己的, 那就转发出去, 如果 IP 地址是自己的, 那就是发给自己的. 根据 IP 头里的标示, 拿掉三层的头, 进行下一层的处理.

    然后根据地址是 TCP 还是 UDP 决定改掉用 process_tcp(buffer) 还是 process_udp(buffer), 同样, 此时 buffer 里已经没有三层的头, 就需要查看第四层, 看一下这个头的类型, 是发起还是应答还是正常的数据包, 如果是数据包,就需要继续交给上层,但是不会再有 process_http(buffer) 函数了, 因为如果是一个网络包处理程序就应该交给应用去处理, 根据第四层里的端口号, 不同的应用监听不同的端口号, 如果发现浏览器在监听这个端口, 那就发给浏览器.

浏览器做的自然就是解析HTML, 显示出页面. 然后电脑的主人看到了页面, 又点了鼠标, 然后动作被浏览器捕获, 浏览器就知道, 又要发起另一个HTTP请求了, 于是使用端口号请求又再次发出. 接着调用 send_tcp(buffer) 给 buffer 加一层 TCP 头, 记录下源端口号. 浏览器会提供目的端口号, 一般为80端口.

然后是 send_layer3(buffer), 加上了一个 IP 的头, 记录下了源 IP 的地址以及目标 IP 的地址.

send_layer2(buffer), 加上 MAC 头, 记录了源MAC地址, 也就是本机器的 MAC 地址, 还有目标的 MAC 地址. 不过要看当前是否知道目标 MAC 地址, 如果不知道就需要经过一定的写一处理过程, 找到 MAC 地址, 反正不能为空.

buffer 的内容完整后就可以从网口发出去了.

ifconfig

Linux 查看 IP 地址的命令:

1
2
3
ifconfig

ip addr

若一个tinyLinux中没有 ifconfig 和 ip addr 命令, 可以安装 nettools 和 iproute2 这两个工具, 但一般情况下都是系统自带的.

运行后输出的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
root@test:~# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether fa:16:3e:c7:79:75 brd ff:ff:ff:ff:ff:ff
inet 10.100.122.2/24 brd 10.100.122.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fec7:7975/64 scope link
valid_lft forever preferred_lft forever

这个命令显示了机器上所有的网卡, 大部分的网卡都会有一个 IP 地址. IP 地址是网卡在网络世界的通讯地址, 相当于现实世界的门牌号.

10.100.122.2 是一个 IP 地址, 被分割为四个部分, 每部分8 bit, 所以 IP 地址总共32位. 因为不能重复, 所以不够用, 于是就有了 IPv6 128位.

32位 IP 地址被分成了5类:

A类: 0 + 网络号(7位) + 主机号(24位)

B类: 1 + 0 + 网络号(14位) + 主机号(16位)

C类: 1 + 1 + 0 + 网络号(21位) + 主机号(8位)

D类: 1 + 1 + 1 + 0 + 多播组号(28位)

E类: 1 + 1 + 1 + 1 + 1 + 0 + 留待后用(27位)

然后根据上面的表格就可以算出A,B,C三类地址所能包含的主机的数量.

类别 IP 地址范围 最大主机数 私有 IP 地址范围
A 0.0.0.0 - 127.255.255.255 16777214 10.0.0.0 - 10.255.255.255
B 128.0.0.0 - 191.255.255.255 65534 172.16.0.0 - 172.31.255.255
C 190.0.0.0 - 223.255.255.255 254 192.168.0.0 - 192.168.255.255

这里有个很大的问题就是C类地址所能包含的主机数量实在是太少了, B类的地址能包含的最大主机数又太多了,一般的企业很难达到这个水准, 空出了很多地址造成浪费.

无类型域间选路(CIDR)

这是一个比较折中的方式, 打破了原来设计的几类地址, 将32位的 IP 地址一分为二, 前面是网络号, 后面是主机号, 10.100.122.2/25, 这个 IP 地址后面有个斜杠, 后面有个24, 这种表示形式就是CIDR, 后面的24意思是32位 IP 地址中, 前24位是网络号, 后8位是主机号.

伴随着 CIDR存在的事 还有广播地址 10.100.122.255 和子网掩码 255.255.255.0.

如果发送一个广播地址, 所有的在 10.100.122 网络里的机器都可以收到.

将子网掩码和 IP 地址进行按位 AND 运算,就得到了网络号.

公有地址私有地址

平时我们看到的数据中心里, 办公室,家里或学习的 IP 地址一般都是私有地址. 因为这些地址允许内部的 IT 人员自己管理, 自己分配, 而且可以重复. 

公有地址是有一个组织来统一分配, 需要去买.如果仅仅是局部使用, 那只需要局部网络的 IP 地址就可以, 但是如果想让全世界访问, 那就得需要共有 IP 地址.

表格中 192.168.0.x 是最常用的 IP 地址, 一般最常见的就是 /24 或 /16.

但是有时候也会出现错误, 例如 16.158.165.91/22 这个CIDR 求这个网络的第一个地址, 子网掩码和广播地址.

如果直接写成 16.158.165.1 那就错了, /22不是8的整数倍, 所以需要先变成二进制来看, 16.158的部分不变, 占了前16位. 165变成二进制为 10100101, 除了前面的16位还剩下六位. 所以这八位前六位是网络号——16.158.<101001>, 而 <01>.91 是机器号.

所以这个网络的第一个第一个地址就是 16.158.<101001><00>.1, 也就是16.158.164.1, 子网掩码是255.255.<111111><00>.0, 也就是 255.255.252.0. 广播地址是 16.158.<101001><11>.255, 也就是15.158.167.255.

script>