计算机网络基础
1. 什么是计算机网络
能让两台或两台以上的计算机相互通信的结构,叫做计算机网络。
为了实现计算机之间能够相互通信,有两个问题需要解决
- 一台计算机如何去找到其它计算机
- 找到其它计算机之后,它们之间如何通讯
为了解决这两个问题,人们定义和开发了两种协议
用于寻址的IP协议
用于通信的TCP协议
2. 创建一个最简单的计算机网络
准备:
两台计算机,一根交叉网线
操作:
-
将两台电脑用网线连起来
-
寻找网络接口(网卡)
首先,你要知道你这台电脑在正在使用什么网络接口。以太网端口通常用“eth”加上一个从0开始的数字来指定。你可以使用ip
命令来查询计算机上的接口:
$ ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ...
link/loopback 00:00:00:00:00:00 brd ...
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> ...
link/ether dc:a6:32:be:a3:e1 brd ...
3: wlan0: <BROADCAST,MULTICAST> ...
link/ether dc:a6:32:be:a3:e2 brd ...
在这个例子中,eth0
是正确的接口名称。
-
分配IP地址
通常情况下,IP地址是从路由器获得的。当一台电脑连接到一个网络时,它请求一个网络地址,路由器通过MAC地址识别到设备,并给这台电脑分配一个IP地址
。这就是计算机在网络上能找到彼此的方法。
在这个简单的网络中,没有路由空荡荡来分配IP地址及注册设备,因此我们需要手动手配IP地址,使用IP
命令来给计算机分配IP地址:
sudo ip address add 192.168.0.0
给另外一台计算机分配IP地址
sudo ip address add 192.168.0.1
现在计算机有了网线连接网口,又有了唯一的IP地址用来识别身份。但是还有一个重要问题:计算机还不知道自己是网络的一部分。
-
设置路由表
路由器的另外一功能是设置计算机A到机算B的网络网络路径,称作路由表
。
路由表可以看作计算机网络的城市地图。
我们可以通过route
命令来查看路由表
$ route
Kernel IP routing table
Destination | Gateway | Genmask | Flags|Metric|Ref | Use | Iface
$
也可以使用ip
命令来查看
$ ip route
$
通过ip
命令一条路由信息:
sudo ip route \
add 192.168.0.0/24 \
dev eth0 \
proto static
这条命令为eth0
接口添加一个地址范围(192.168.0.0~192.168.0.255)的路由表。
它将路由协议设置为“静态”
。
通过route
命令来查询路由表:
$ route
Kernel IP routing table
Destination | Gateway | Genmask | ... | Iface
link-local | 0.0.0.0 | 255.255.255.0 | ... | eth0
或使用ip
命令从不同角度来查询路由表:
$ ip route
169.254.0.0/24 dev eth0 proto static scope link
-
开始通信
现在你的网络有了传输方式、寻址方法以及网络路由表。你可以使用你的计算机联系别的计算机了。
向别的计算机发送一个最简章的消息,就是ping
$ ping -c1 169.254.0.2
64 bytes from 169.254.0.2: icmp_seq=1 ttl=64 time=0.233 ms
--- 169.254.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.244/0.244/0.244/0.000 ms
你可以通过下面的命令看到与你交互的计算机
$ ip neighbour
169.254.0.2 dev eth0 lladdr e8:6a:64:ac:ef:7c STALE
3. 扩展你的网络
使用物理层设备——集线器(hub)
对于多台计算机入网,使用一对一的网线接口的方案是不可行的。所以人们发明了集线器。
网络内的计算机都通过网线连接到集线器。它能将收到的消息,发送给所有连在它上面的计算机。
由每个计算机本身进行识别这条消息是不是给它的,识别方法就是消息包里的MAC地址
。
如A 在发送数据包给 B 时,只要在头部拼接一个这样结构的数据,就可以了。
B判断目标MAC,是发给自己的,就收下。
好处:使整体物理布局干净不少;
不足:广播式传输消息,既不安全,也不节省网络资源。
使用数据链路层设备——交换机
那么能不能将集线器弄得更智能一些,只转发给目标MAC地址指向的那台电脑。
这样的设备就是交换机
。
交换机里有一张MAC地址表
,记录着每一个MAC对应哪个端口。
在具体设备发消息时,交换机会查一下数据头,看一下目标MAC在哪个端口上,然后直接将消息转发过去。
那么MAC地址表是怎么建立的呢?
答案:交换机自动建立。
刚一开始时,MAC地址表是空的。交换机此时是用广播式方式给各个设备通信,与集线器一样。
当一电脑发起消息,交换机收到后,就能知道当前MAC对应哪个端口,并做记录。
经过该网络中的机器不断地通信,交换机最终将MAC地址表建立完毕。
同时,交换机之间可又相互串联,用来增加接入电脑的数量
。
随着接入电脑的越来越多,交换机里的MAC地址端口映射表会越来越大,由于实际机器的限制,这个表不能无限增加,所以这种方法能接入的电脑也是有个上限的。
那么怎么办呢?
添加网络层设备--路由器
(这一段超精彩,感谢原作者:闪客sun)
既然串联交换机的数量有上限,那么能不能做一个设备,用来连接两个或多个交换机网络呢?这个设备每个端口都有独立MAC,用来连接交换机群,而且能实现从交换机群之间的数据转发。
这个设备就是路由器
,它的功能就是做交换机群之间的数据包转发,并且每个与交换机群相连的端口有一个自己独立的MAC
。
那么问题来了,在这种网络中,计算机之间是如何通信的呢?
情形1:A->B
A,B在同一个交换机下,所以利用交换机就可以相互通信,不经过路由器
情形2:A->路由器->C
那么问题来了,
A怎么知道要给C发消息,要先发消息给路由器?
因为每个交换机群都被路由器分配了一个子网段
,当A发现C的IP地址与它不在同一网段,A会直接将消息发给路由器。
怎么划分子网?
答案:依据当前网络拓扑结构,分配不同的IP地址格式。
由于MAC值是出厂就被厂家分配好了,而且你到市场上买的每个网卡MAC号也各自没有规律;一旦用这MAC来划分好子网,以后这个网络结构维护起来会极为困难。
所以,采用了对网络上的每台电脑进行重新编号的方法
;
如采用32bit来表示
11000000101010000000000000000001
你觉得有些不清晰,于是把它分成四个部分,中间用点相连。
11000000.10101000.00000000.00000001
你还觉得不清晰,于是把它转换成 10 进制。
192.168.0.1
这个地址有一个响亮的名字,IP 地址
IP地址用32bit,被称为IPv4(internet protocol version 4)
;
IP地址用128bit,被称为IPv6(internet protocol version 6)
;
现在每一台电脑既有自己的MAC地址,又有自己的IP地址。只不过IP地址只是软件层面的,可以随时修改,比MAC地址灵活方便太多。
那么发送端如何知道对方与自己有没有处在同一子网中呢?
答案:IP地址与子网mask
采用源IP与目的IP分别与子网mask进行位与运算,算出来的结果相等则是在同一个子网,不相等就是在不同子网,就是这么简单。
比如
A电脑:192.168.0.1 & 255.255.255.0 = 192.168.0.0
B电脑:192.168.0.2 & 255.255.255.0 = 192.168.0.0
C电脑:192.168.1.1 & 255.255.255.0 = 192.168.1.0
D电脑:192.168.1.2 & 255.255.255.0 = 192.168.1.0
那么 A 与 B 在同一个子网,C 与 D 在同一个子网,但是 A 与 C 就不在同一个子网,与 D 也不在同一个子网,以此类推。
如交换机群1被分配在了192.168.1.x,交换机群2被分配在了192.168.2.x,每个交换机群最多可以接254台电脑(0和255用来保留)。
这样就可以依据你的网络组织结构,自由灵活地分配IP地址了。
有了上面的介绍,我们给上面的组网方式中的每一台设备加上自己的IP
由于有IP的概念,所以现在的数据包除了MAC字段外,还要加上IP字段。
A->路由器
这段数据包如下:
路由器->C
这段数据包如下:
所以如果A给C发消息,A和C的IP地址分别&A机器配置的子网mask,发现其值不相等,则A将数据包发给路由器就不管了。
A怎么知道哪个是路由器
答案:在A上要设置默认网关
其实说A发给路由器不准确,应该说A会把包发给默认网关。
对于A来说,A只能直接把包发给在相同子网下的某个IP上,所以发给路由器还是发给某个电脑,对A来说是不关心的,只要这个设备有个IP地址就行
。
所以默认网关,就是A在自己电脑里配置的一个IP地址,只要有数据要发给别的子网设备时,只需要将数据发给这个IP地址就可以了。
路由器怎么知道要转发给C
答案:路由表
现在A给C发的数据包,已经成功发到路由器这里了,最后一个问题就是,路由器怎么知道,收到的数据包该从自己的哪个PORT出去,才能直接或间接地最终送到C呢。
路由器收到的数据包里有目的IP,也就是C的IP的地址,需要转化成从自己的哪个端口出去,类比交换机,应该有个表来管理子网与路由器端口的对应关系
。
这个表就叫路由表
。
路由表举例如下:
目的地址 | 下一跳 | 端口 |
---|---|---|
192.168.0.0/24 | 0 | |
192.168.1.0/24 | 1 |
子网mask (255.255.255.0,从左向右数,一共24个1,故也可用/24来表示)
第一行表示,192.168.0.xxx这个子网,接在了0号端口;
第二行表示,192.168.1.xxx这个子网,连在了1号端口;
那么在刚一开始时,A是怎么知道C的MAC值的呢?
答案:arp协议
在现实中,我们是知道对方机器的IP地址的,但是不知道对方MAC值。这时可以通过ARP协议,能找到一个IP地址下的MAC值。
电脑里也会存一张ARP缓存表,表中记录着IP与MAC值的对应关系。
IP地址 | MAC地址 |
---|---|
192.168.0.2 | BBBB |
一开始这个表是空的,电脑A为了知道电脑B(192.168.0.2)的MAC地址,会广播一条ARP请求,B收到请求后,会带上自己的MAC值给A一个响应。A收到后便更新了自己的ARP表。 | |
这样大家不断广播ARP请求,最终所有电脑里都将ARP缓存表更新完整。 |
总结一下
电脑视角:
- 首先要知道自己的IP以及对方的IP;
- 能过子网mask判断我们是否在同一个子网;
- 在同一个子网,通过ARP获取对方MAC后,将数据直接发出去;
- 不在同一个子网,能过ARP获取默认网关的MAC后,将数据发出去;
交换机视角
- 我收到的数据包必须有目标MAC地址
- 通过MAC地址表查映射关系
- 查到了就按映射关系里的端口发出去
- 查不到就向所有的端口发出去
路由器视角
- 我收到的数据包必须有目标IP地址
- 通过路由表查映射关系
- 查到了就按照映射关系从指定端口发出
- 查不到则返回一个路由不可达的数据包
涉及到的三张表分别是
- 交换机中有
MAC地址表
用于映射MAC地址和它的端口 - 路由器中有
路由表
用于映射IP地址(段)和它的端口 - 电脑和路由器中都有
ARP缓存表
用于缓存IP和MAC的映射关系
这三张表是怎么来的
MAC地址表
是通过网络中的各节点不断的通过交换机通信,不断完善起来的;
路由表
是各种路由算法+人工配置逐步完善起来的;
ARP缓存表
是不断通过ARP协议请求逐步完善起来的;
知道了以上这些,目前网络上两个节点是如何发送数据包的这个过程,就完全可以解释通了。
最终实战
在本图中,路由器1连接了路由器2,所以其路由表有了下一跳地址
这个概念。最终必须能映射到一个端口号,然后从这个端口号把数据包发出去。
目的地址 | 下一跳 | 端口 |
---|---|---|
192.168.0.0/24 | 0 | |
192.168.0.254/32 | 0 | |
192.168.1.0/24 | 1 | |
192.168.1.254/32 | 1 | |
192.168.2.0/24 | 192.168.100.5 | |
192.168.100.0/24 | 2 | |
192.168.100.4/32 | 2 |
这时如果 A 给 F 发送一个数据包,能不能通呢?如果通的话整个过程是怎样的呢?
详细过程动画描述:
详细过程文字描述:
A(192.168.0.1)
通过子网mask(255.255.255.0)
计算出自己与F(192.168.2.2)
并不在同一个子网内,于是将数据发给它的默认网关(192.168.0.254)
;- A通过ARP找到默认网关 192.168.0.254 的MAC地址;
- A将源MAC地址(AAAA)与网关地址(ABAB)封装在数据链路层头部,又将IP地址(192.168.0.1)和目的IP地址(192.168.2.2)封装在网络层头部,然后发包;注意:这里千万不要以为填写的是默认网关的 IP 地址,从始至终这个数据包的两个 IP 地址都是不变的,只有 MAC 地址在不断变化!
- 交换机1收到数据包后,发现目标MAC地址是ABAB,通过查自己的MAC端口对应表,转发给相应端口上的路由器1;
- 数据包来到了路由器1,发现其目标IP地址是192.168.2.2,查看其路由表,发现了下一跳的地址是192.168.100.5;
- 此时路由器1再次查找路由表,发现下一跳的IP子网在端口2,于是从2号端口里转发出去。
- 路由器2收到了数据包,看到其目的IP是192.168.2.2,查询其路由表,匹配到端口号为1,准备从1号口将数据包发送出去;
- 但是路由器需要知道192.168.2.2的MAC地址,这样地能让下面的交换机进行转发。于是查看其ARP缓存表,找到其MAC地址为FFFF,将数据包里的目标MAC换为FFFF,并从1号端口把包发出去;
- 交换机3收到了数据包,发现包里的目的MAC地址为FFFF,查询MAC地址端口映射表,发现该MAC设备在6号端口,于是从6号端口把数据包发出去。
- F最终收到了数据包,并且发现目的MAC值就是自己,于是收下了这个包。
后记
至此,经过物理层
,数据链路层
,网络层
这前三层的协议,以及根据这些协议设计的各种网络设备(网线,集线器,交换机,路由器)
。理论上,只要有了对方的IP地址,就可以将地球上任意位置的两个节点连通。
为了简化操作,实际也会用到以下服务
DHCP服务
,为加入网络的设备分配和跟踪IP地址;DNS服务
,将域名转换为IP地址;防火墙
,控制这个网络的外部访问以及访问外部的动作;