第 11 课 · Découverte

互联网是怎么工作的

一个包、一个地址、一个端口、一本电话本。Louis Pouzin 发明了邮局——剩下的只是分拣。

~11 min7 个关卡
▶ 视频🧩 练习📄 备忘单

42 秒 · 含中文字幕 · 8.7 Mo

你会学会的 7 件事

第 11 课:互联网是怎么工作的

Regarde la leçon (42 s) : 1971, un Français invente le paquet qui voyage tout seul. Ensuite, tout le reste n'est que de l'adresse, des portes et un annuaire.

地址:四个数字三个点

Écris `adresse(a, b, c, d)` : l'adresse IP en quatre nombres — `adresse(203, 113, 7, 42)` → `"203.113.7.42"`. Quatre octets, trois points, dans l'ordre.

Pouzin 的数据报

Écris `datagramme(src, dst, donnees)` : le paquet complet — un Hash avec `"src"`, `"dst"` et `"data"`. Idée de Louis Pouzin en 1971 : tout le voyage est DANS le paquet.

同一地址,另一扇门

Écris `port(service)` : `"http"` → 80 · `"https"` → 443 · `"ssh"` → 22 · tout autre service → `nil`. Même machine, autre porte : c'est ça qui sépare le web du SSH.

DNS 电话本

Écris `resoudre(nom)` : le DNS — `"slopcourse.fr"` → `"203.113.7.42"` · `"42.fr"` → `"198.51.100.42"` · nom inconnu → `nil`. Tu tapes un nom, il te rend une adresse.

抓住这个包

Écris `attrape?(reseau, mon_port, dst, port)` : true SI `dst` commence par MON réseau (comme `"10.0.0."`) ET que le port du paquet vaut `mon_port`. Bon réseau + bonne porte — sinon tu laisses passer.

第 11 课:OK

Sans aide : `joue(moi, paquet)` — 1) résous `moi` dans ce DNS : `"slopcourse.fr"` → `"203.113.7.42"`, `"42.fr"` → `"198.51.100.42"` · 2) mon réseau = les trois premiers chiffres + `"."` · 3) attrape si `paquet["dst"]` est sur mon réseau ET `paquet["port"] == 443`. Nom inconnu → `false`.

分享这一课

← 全部课程

📄 备忘单

打印出来贴显示器上,就当是你自己的主意

📄 备忘单 — 互联网是怎么工作的(Pouzin 与数据报)

1971 年,Louis Pouzin 发明了自带地址的包。从那以后,互联网就是一座巨大、分拣极好的邮局:一个地址、一扇门、一本电话本。

历史,三行

年份 发生了什么 带来了什么
1971 Louis Pouzin(CYCLADES)发明数据报 自治的包:整趟旅程都在里面
1974 Cerf & Kahn(TCP/IP)受其启发 互联的契约:尽力而为,不保路线
今天 每秒数十亿个包 你的四个概念 · 地址 · 端口 · DNS · 分拣

Pouzin:不在两台机器之间修专线(电话那套),而是切成包、逐个地址、直接发。 每台路由器只做本地分拣。这就是奠基的那个手势。

1. IP 地址:先街区,再门牌

def adresse(a, b, c, d)
  "#{a}.#{b}.#{c}.#{d}"
end
adresse(203, 113, 7, 42)   # => "203.113.7.42"

# 网络 = 这里的前三个八位组(我们游戏的简化)
ip.split(".")[0..2].join(".") + "."   # => "203.113.7."

开头说网络(街区),结尾说主机(门牌)。同一条街,别的门号。

2. 数据报:完整的信封

def datagramme(src, dst, donnees)
  { "src" => src, "dst" => dst, "data" => donnees }
end
datagramme("10.0.0.1", "10.0.0.2", "ping")
# => {"src"=>"10.0.0.1", "dst"=>"10.0.0.2", "data"=>"ping"}

寄件人、收件人、内容:别处什么都不用查。(这就是 Pouzin 的想法。)

3. 门:同一地址,多个服务

case service
when "http"  then 80
when "https" then 443
when "ssh"   then 22
else nil          # 不认识的服务:对我们来说这扇门不存在
end

一台机器,好几扇门:地址带你到房子,端口带你到那个房间。

4. DNS:电话本

case nom
when "slopcourse.fr" then "203.113.7.42"
when "42.fr"         then "198.51.100.42"
else nil
end

你输一个名字,它还你一串数字。没有魔法:一个超大号 case/when (真正的 DNS 就是几百万行同类代码,分层摆好)。

5. 游戏:抓住这个包

def attrape?(reseau, mon_port, dst, port)
  dst.start_with?(reseau) && port == mon_port
end
attrape?("10.0.0.", 8080, "10.0.0.42", 8080)   # => true
attrape?("10.0.0.", 8080, "192.168.1.5", 8080) # => false —— 别的街区
attrape?("10.0.0.", 8080, "10.0.0.42", 22)     # => false —— 别的门

两个条件,缺一不可。 一个 &&——互联网的一半过滤逻辑就在这: 我的网络 并且 我的端口。

完整的一趟(你的路由器在做的,一个函数)

# 1. DNS:名字 → 地址   2. 地址 → 网络   3. 包:网络 + 端口 是不是我?
# 4. 是 → 抓住   5. 否 → 放行(会有人抓住它)

以后别再说

  • 「互联网把数据送进管子里」 → 自治的包,每个自带地址
  • 「需要永久连接」 → Pouzin 在 1971 年就证伪了
  • 「DNS 很魔法」 → 名字 → 地址的通讯录;你自己写十行 Ruby 也行

SlopCourse Microduck — 从 slop 到干净的代码。