Ⅰ. 网络结构

Linux系统编程笔记(12)——网络-萤火

1.数字用户线路DSL

Linux系统编程笔记(12)——网络-萤火

2.混合光纤同轴电缆HFC

Linux系统编程笔记(12)——网络-萤火

3.以太网

Linux系统编程笔记(12)——网络-萤火

4.移动网络

Linux系统编程笔记(12)——网络-萤火

Ⅱ. 查看IP

1.命令

(1) ifconfig

(2) ip addr

这个命令显示了这台机器上所有的网卡。大部分的网卡都会有一个IP地址。
IP地址是一个网卡在网络世界的通讯地址,相当于我们现实世界的门牌号码。
既然是门牌号码,不能大家都一样,不然就会起冲突。比如说,假如大家都叫六单元1001号,那快递就找不到地方了。所以有时候咱们的电脑弹出网络地址冲突,出现上不了网的情况,多半是IP地址冲突了。

2.分类

IPV4地址有32位,而且被分为了5类:

Linux系统编程笔记(12)——网络-萤火
看0在第几位,第一位是A类,第二类是B类,第三位是C类…

下面这个表格,详细地展示了A、B、C三类地址所能包含的主机的数量:

Linux系统编程笔记(12)——网络-萤火
主机号全0作为网络号,全1是广播地址,因此最大主机数要减去这两个IP

3.无类型域间选路(CIDR)

本来32位IP地址就不够,还被分为了5类,现在想想,真是太奢侈了。于是有了一个折中的方式叫作无类型域间选路,简称CIDR。这种方式打破了原来设计的几类地址的做法,将32位的IP地址一分为二,前面是网络号,后面是主机号。
从哪里分呢?你如果注意观察的话可以看到,192.168.0.169/24,这个IP地址中有一个斜杠,斜杠后面有个数字24。这种地址表示形式,就是CIDR。后面24的意思是,32位中,前24位是网络号,后8位是主机号。
伴随着CIDR存在的,一个是广播地址,brd 192.168.0.255。如果发送这个地址,所有192.168.0网络里面的机器都可以收到。另一个是子网掩码,netmask 255.255.255.0。

子网掩码 & IP地址 = 网络号
~子网掩码 & IP地址 = 主机号

4.公有IP和私有IP地址

Linux系统编程笔记(12)——网络-萤火

表格最右列是私有IP地址段。平时我们看到的数据中心里、办公室、家里或学校的IP地址,一般都是私有IP地址段。因为这些地址允许组织内部的IT人员自己管理、自己分配,而且可以重复。因此,你家里的某个私有IP地址段和我家里的可以是一样的。
公有IP地址由组织统一分配,你需要去买。如果你搭建一个网站,给你家里的人使用,让路由器自动给你分配一个IP地址就行。但是假如你要做一个类似bilibili这样的网站,就需要有公有IP地址,这样全世界的人才能访问。

5.MAC地址

link/ether 52:54:00:0d:cc:99

这个被称为MAC地址,是一个网卡的物理地址,用十六进制,6个byte表示MAC地址全局唯一,不会有两个网卡有相同的MAC地址,而且网卡自生产出来,就带着这个地址。

IP地址类似收货地址
MAC地址类似身份证
所在虽然MAC地址是全局唯一的,但是在茫茫网络世界中,依然需要IP地址作为定位寻找。

6.网络设备的状态标识

<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast

这个叫做net_device flags,网络设备的状态标识

  • UP:表示网卡处于启动的状态
  • BROADCAST:表示这个网卡有广播地址,可以发送广播包
  • MULTICAST:表示这个网卡可以发送多播包
  • LOWER_UP:表示L1是启动的,也即网线插着呢
  • MTU1500:是指最大传输单元MTU为1500,这是以太网的默认值,以太网规定正文部分不允许超过1500个字节。正文里面有IP的头、TCP的头、HTTP的头。如果放不下,就需要分片来传输。
  • qdisc pfifo_fast:全称是queueing discipline,叫排队规则。内核如果需要通过某个网络接口发送数据包,它都需要按照qdisc(排队规则)把数据包加入队列。最简单的qdisc是pfifo,它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。pfifo_fast稍微复杂一些。

Ⅲ. DHCP

新来的机器使用IP地址0.0.0.0发送了一个广播包,目的IP地址为255.255.255.255。广播包封装了UDP,UDP封装了B00TP。其实DHCP是B00TP的增强版。
在这个广播包里面,新人大声喊:我是新来的(Boot request),我的MAC地址是这个,我还没有IP,谁能给租给我个IP地址!

Linux系统编程笔记(12)——网络-萤火

如果网络里面配置了DHCP Server的话,他就相当于这些IP的房东。他立刻能知道来一个“新人”,需要租给它一个IP地址,这个过程我们称为DHCP Offer,,DHCP Server为此客户保留为它提供的IP地址,不会为其他DHCP客户分配此IP地址

Linux系统编程笔记(12)——网络-萤火

DHCP Server仍然使用广播地址作为目的地址,因为此时请求分配IP的新机器还没有自己的IP。DHCP Server回复说,我分配了一个可用的IP给你,你看如何?除此之外,服务器还发送了子网掩码、网关和IP地址租用期等信息

新来的机器很开心,它的“吼”得到了回复,并且有人愿意租给它一个IP地址了,这意味着它可以在网络上立足了。
当然更令人开心的是,如果有多个 DHCP Server,这台新机器会收到多个IP地址,简直受宠若惊。它会选择其中一个DHCP Offer,一般是最先到达的那个,并且会向网络发送一个DHCP Request广播数据包,包中包含客户端的MAC地址、接受的租约中的IP地址、提供此租约的DHCP服务器地址等,并告诉所有DHCP Server它将接受哪一台服务器提供的IP地址,告诉其他DHCP服务器,谢谢你们的接纳,并请求撤销它们提供的IP地址,以便提供给下一个IP租用请求者

Linux系统编程笔记(12)——网络-萤火

当DHCP Server接收到客户机的DHCP request之后,会广播返回给客户机一个 DHCP ACK消息包,表明已经接受客户机的选择,并将这一IP地址的合法租用信息和其他的配置信息都放入该广播包,发给客户机,欢迎它加入网络大家庭。
最终租约达成的时候,还是需要广播一下,让大家都知道。

Linux系统编程笔记(12)——网络-萤火

1.IP地址的收回和租期

既然是租房子,就是有租期的。租期到了,管理员就要将IP收回。
如果不用的话,收回就收回了。就像你租房子一样,如果还要续租的话,不能到了时间再续租,而是要提前一段时间给房东说。DHCP也是这样。
客户机会在租期过去50%的时候,直接向为其提供IP地址的 DHCP Server发送DHCP request消息包。客户机接收到该服务器回应的DHCP ACK消息包,会根据包中所提供的新的租期以及其他已经更新的TCP/IP参数,更新自己的配置。这样,IP租用更新就完成了。

Ⅳ. ARP请求、ICMP请求

1.什么是协议?

就是游戏规则。

  • 语法:就是这一段内容要符合一定的规则和格式。例如,这一部分写几个字节,下一个部分写几个字节。
  • 语义:就是这一段内容要代表某种意义。例如这几个字节什么意思,那几个字节什么意思,代表什么。
  • 顺序:就是先干啥,后干啥。例如,先请求租房子,后提供offer,再请求签合同,最后确认合同成立并公示。

2.OSI七层模型:开放式系统互联通信参考模型

Linux系统编程笔记(12)——网络-萤火

3.TCP/IP五层模型

Linux系统编程笔记(12)——网络-萤火

4.物理层:如何在宿舍里自己组网玩联机游戏

梦开始的地方:有单机游戏可以打,比如说《拳皇》、《合金弹头》。两个人用一个键盘,打得火热。

后来,有第二个人买了电脑,那两台电脑能不能连接起来呢?
一根网线,有两个头。一头插在一台电脑的网卡上,另一头插在另一台电脑的网卡上。水晶头要做交又线,用的就是所谓的1-3、2-6交叉接法。水晶头的第1、2和第3、6脚,它们分别起着收、发信号的作用。将一端的1号和3号线、2号和6号线互换一下位置,就能够在物理层实现一端发送的信号,另一端能收到。

等到第三个哥们也买了一台电脑,怎么把三台电脑连在一起呢?
有一个叫做Hub的东西,也就是集线器。这种设备有多个口,可以将宿舍里的多台电脑连接起来。但是,和交换机不同,集线器没有大脑,它完全在物理层工作。它会将自己接收到的每一个字节,都复制到其他端口上去。这是第一层物理层联通的方案。

5.数据链路层

Hub采取的是广播的模式,如果每一台电脑发出的包,宿舍的每个电脑都能收到,那就麻烦了。这就需要考虑这几个问题:

  1. 这个包是发给谁的?谁应该接收?
  2. 大家都在发,会不会产生混乱?有没有谁先发、谁后发的规则?
  3. 如果发送的时候出现了错误,怎么办?

这几个问题,都是第二层,数据链路层,也即MAC层要解决的问题。

解决第一个问题就牵扯到第二层的网络包格式。对于以太网,第二层的最开始,就是目标的MAC地址和源的MAC地址。

Linux系统编程笔记(12)——网络-萤火

对于以太网,第二层的最后面是CRC,也就是循环冗余检测。通过XOR异或的算法,来计算整个包是否在发送的过程中出现了错误,主要解决第三个问题。

MAC的全称是 Medium Access Control,即媒体访问控制。控制什么呢?
其实就是控制在往媟体上发数据的时候,谁先发、谁后发的问题。防止发生混乱。这解决的是第二个问题。这个问题中的规则,学名叫多路访问。有很多算法可以解决这个问题。比如以下这三种方式:

  • 方式一:分多个车道。每个车一个车道,你走你的,我走我的。这在计算机网络里叫作信道划分
  • 方式二:抢令牌,轮着来,谁抢到谁走。这在计算机网络里叫作轮流协议
  • 方式三:不管三七ニ十ー,有事儿先出门,发现特堵,就回去。错过高峰再出。我们叫作随机接入协议。著名的以太网,用的就是这个方式。

6.网络层:IP层

当然电脑之间进行连接,还需要配置这两台电脑的IP地址、子网掩码和默认网关。要想电脑之间能够通信,这三项必须配置成为一个网络,比如一个是192.168.0.1/24,另一个是192.168.0.2/24,否则是不通的。

这里还有一个没有解决的问题,当源机器知道目标机器的时候,可以将目标地址放入包里面,如果不知道呢?一个局域网里面接入了N台机器,我怎么知道每个MAC地址是谁呢?

7.ARP协议

要解决上面的问题,就需要引入ARP协议。
ARP协议:已知IP地址,求MAC地址的协议。

在一个局域网里面,当知道了IP地址,不知道MAC地址,该怎么办呢?靠“吼”。

Linux系统编程笔记(12)——网络-萤火
可以通过命令arp -a查看ARP表

ARP数据报文格式:

Linux系统编程笔记(12)——网络-萤火

为了避免每次都用ARP请求,机器本地也会进行ARP缓存。当然机器会不断地上线下线,IP也可能会变,所以ARP的MAC地址缓存过一段时间就会过期

好了,至此我们宿舍四个电脑就组成了一个局域网。
用Hub连接起来,就可以玩游戏了。

8.交换机

这种组网的方法,对一个宿舍来说没有问题,但是一旦机器数目增多,问题就出现了。因为Hub是广播的,不管某个接口是否需要,所有的Bit都会被发送出去,然后让接收主机来判断是不是需要。这种方式路上的车少就没问题,车一多,产生冲突的概率就提高了。而且把不需要的包转发过去,纯属浪费。

看来Hub这种不管三七二十一都转发的设备是不行了,需要个智能的设备。因为每个口都只连接一台电脑,这台电脑又不怎么换IP和MAC地址,只要记住这台电脑的MAC地址,如果目标MAC地址不是这台电脑的,这个口就不用转发了。

交换机怎么知道每个口的电脑的MAC地址呢?

这需要交换机会学习。一台MAC1电脑将一个包发送给另一台MAC2电脑,当这个包到达交换机的时候,一开始交换机也不知道MAC2的电脑在哪个口,所以没办法,它只能将包转发给除了来的那个口之外的其他所有的口。但是,这个时候,交换机会干一件非常聪明的事情,就是交换机会记住, MAC1是来自一个明确的口。以后有包的目的地址是MAC1的,直接发送到这个口就可以了。
当交换机作为一个关卡一样,过了一段时间之后,就有了整个网络的一个结构了,这个时候,基本上不用广播了,全部可以准确转发。当然,每个机器的IP地址会变,所在的口也会变,因而交换机上的学习的结果,我们称为转发表,是有一个过期时间的。
有了交换机,一般来说,你接个几十台、上百台机器打游戏,应该没啥问题。

9.ICMP与ping

无论是在宿舍,还是在办公室,或者运维一个数据中心,我们常常会遇到网络不通的问题。那台机器明明就在那里,你甚至都可以通过机器的终端连上去看。它看着好好的,可是就是连不上去,究竟是哪里出了问题呢?

一般情况下,你会想到pingー下。那ping是如何工作的呢?

ping是基于ICMP协议工作的。ICMP全称Internet Control Message Protocol就是互联网控制报文协议。

网络包在异常复杂的网络环境中传输时,常常会遇到各种各样的问题。当遇到问题的时候,总不能“死个不明不白”,要传出消息来,报告情况,这样才可以调整传输策略。这就相当于我们经常看到的电视剧里,古代行军的时候,为将为帅者需要通过侦察兵、哨探或传令兵等人肉的方式来掌握情况,控制整个战局。

ICMP报文是封装在IP包里面的。我们先看一下IP数据报格式。

Linux系统编程笔记(12)——网络-萤火
  • IP数据报的首部长度和数据长度都是可变长的,但总是4字节的整数倍。
  • 对于IPv4,4位版本字段是4。
  • 4位首部长度的数值是以4字节为单位的,最小值为5,也就是说首部长度最小是4×5=20字节,也就是不带任何选项的IP首部,4位能表示的最大值是15,也就是说首部长度最大是60字节。
  • 8位T0S字段有3个位用来指定IP数据报的优先级(目前已经废弃不用),还有4个位表示可选的服务类型(最小延迟、最大吞吐量、最大可靠性、最小成本)还有一个位总是0。
  • 总长度是整个数据表(包括IP首部和IP层payload)的字节数。
  • 每传一个IP数据报,16位的标识加1,可用于分片和重新组装数据报。
  • 3位标志和13位片偏移用于分片
  • TTL(Time to live)是这样用的:源主机为数据包设定一个生存时间,比如64,没过一个路由器,就丢弃该包,因此这个生存时间的单位不是秒,而是跳(hop)。
  • 协议字段指示上层协议是TCP、UDP、ICMP还是IGMP。
  • 然后是校验和,只校验IP首部,数据的校验由更高层协议负责。
  • IPv4的IP地址长度为32位。

ICMP报文是封装在IP包里面的。因为传输指令的时候,肯定需要源地址和目标地址。它本身非常简单。因为作为侦察兵,要轻装上阵,不能携带大量的包袱。

Linux系统编程笔记(12)——网络-萤火
补充:Type也是8位,校验和应该是16位

ICMP报文有很多的类型,不同的类型有不同的代码。

Linux系统编程笔记(12)——网络-萤火
  • 最常用的类型是主动请求为8,主动请求的应答为0。
  • 查询报文类型我们经常在电视剧里听到这样的话:主帅说,来人哪!前方战事如何,快去派人打探,一有情况,立即通报!这种是主帅发起的,主动查看敌情,对应ICMP的查询报文类型。例如,常用的ping就是查询报文,是一种主动请求,并且获得主动应答的ICMP协议。所以,ping发的包也是符合ICMP协议格式的,只不过它在后面増加了自己的格式。
  • 对ping的主动请求,进行网络抓包,称为ICMP ECHO REQUEST。同理主动请求的回复,称为ICMP ECHO REPLY。比起原生的ICMP,这里面多了两个字段,一个是标识符。这个很好理解,你派出去两队侦查兵,一队是侦查战况的,一队是去查找水源的,要有个标识オ能区分。另一个是序号,你派出去的侦查兵,都要编个号。如果派出去10个,回来10个,就说明前方战况不错;如果派出去10个,回来2个,说明情况可能不妙。
  • 另一种就是差错报文:
    • 终点不可达
    • 源站抑制
    • 时间超时
    • 路由重定向
      差错报文的结构相对复杂一些。除了前面还是IP,ICMP的前8个字节不变,后面则跟上出错的那个IP包的IP头和IP正文的前8个字节。而且这类侦察兵特别恪尽职守,不但自己返回来报信,还把一部分遗物也带回来。

ping的发送和接收过程:

Linux系统编程笔记(12)——网络-萤火
ps:省略了解包过程5、10

Ⅴ. NAT网关

1.路由器

家庭路由器会有内网网口和外网网口。把外网网口的线插到光猫拉出的网线的网口上,将这个外网网口配置成和光猫的局域网一样。内网网口连上家里的所有的电脑。(内外网的网段不能一样

路由器将多个局域网相连,每个局域网的出口就叫网关。

Linux系统编程笔记(12)——网络-萤火
  • 如果是同一个网段,例如,你访问你旁边的手机,那就没网关什么事情,直接将源地址和目标地址放入IP头中,然后通过ARP获得MAC地址,将源MAC和目的MAC放入MAC头中,发出去就可以了。
  • 如果不是同一网段,该怎么办?这就需要发往默认网关Gateway。Gateway的地址定是和源IP地址是一个网段的。往往不是第一个,就是第二个。例如192.168.1.0/24这个网段, Gateway往往会是192.168.1.1/24或者192.168.1.2/24。如何发往默认网关呢?网关不是和源IP地址是一个网段的么?这个过程就和发往同一个网段的其他机器是一样的:将源地址和目标IP地址放入IP头中,通过ARP获得网关的MAG地址,将源MAC和网关的MAC放入MAC头中发送出去。网关所在的端口,例如192.168.1.1/24将网络包收进来,然后接下来怎么做,就完全看网关的了。

网关往往是一个路由器,是一个三层转发的设备。
啥叫三层设备?就是把MAC头和IP头都取下来,然后根据里面的内容,看看接下来把包往哪里转发的设备。
很多情况下,人们把网关就叫做路由器。其实不完全准确。
准确的说:路由器是一台设备,它有多个网口或者网卡,分别连着多个局域网。每个网卡的IP地址都和局域网的IP地址相同的网段,每个网卡都是它握住的那个局域网的网关。任何一个想发往其他局域网的包,都会到达其中一个网关,被拿进来,拿下MAC头和IP头,看看,根据自己的路由算法,选择另一个网口,加上IP头和MAC头,然后扔出去。

3. 静态路由

静态路由,其实就是在路由器上,配置一条一条规则。
每当要选择从哪个网口抛出去的时候,就一条一条地匹配,找到符合的规则,按规则中设置得那样,从某个口抛出去。

#Windows查看路由表
route print

# Linux查看路由表
route
netstat -rn

网络目标(Destination) 网络掩码(Genmask) 网关(Gateway) 接口(Iface) 跃点数(Metric)
0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.104 25
这表示发向任意网段的数据通过本机接口192.168.1.104被送往一个默认的网关:192.168.1.1,它的管理距离是25,管理距离指的就是在路径选择的过程中信息的可信度,管理距离越小的,可信度越高。

127.0.0.0 255.0.0.0 在链路上 127.0.0.0 331
A类地址中127.0.0.0留在本地调试使用,所以路由表中发向127.0.0.0网络的数据通过本地回环127.0.0.1发送给指定的网关:127.0.0.1,也就是从自己的回环接口发到自己的回环接口,这将不会占用局域网的带宽。

192.168.1.0 255.255.255.0 在链路上 192.168.1.104 281
这里的目的网络与本机处于一个局域网,所以发向网络192.168.1.0(也就是发向局域网的数据)在链路上,这便不再需要路由器或不需要交换机交换,增加了传输效率。

4.转发网关

Linux系统编程笔记(12)——网络-萤火

服务器A要访问服务器B:

  • 首先,服务器A会思考,192.168.4.101和我不是一个网段的,因而需要先发给网关。那网关是谁呢?已经静态配置好了,网关是192.168.1.1。
  • 网关的MAC地址是多少呢?发送ARP获取网关的MAC地址,然后发送包。包的内容是这样的:
    • 源MAC:服务器A的MAC
    • 目标MAC:192.168.1.1这个网口的MAC
    • 源IP:192.168.1.101
    • 目标1P:192.168.4.101
  • 包到达192.168.1.1这个网口,发现MAC一致,将包收进来,开始思考往哪里转发。
    在路由器A中配置了静态路由之后,要想访问192.168.4.0/24,要从192.168.56.1这个口出去,下一跳为192.168.56.2。
    于是,路由器A思考的时候,匹配上了这条路由,要从192.168.56.1这个口发出去,发给192.168.56.2,那192.168.56.2的MAC地址是多少呢?路由器A发送ARP获取192.168.56.2的MAC地址,然后发送包。包的内容是这样的:
    • 源MAC:192.168.56.1的MAC
    • 目标MAC:192.168.1.2这个网口的MAC
    • 源IP:192.168.1.101
    • 目标1P:192.168.4.101
  • 在路由器B中配置了静态路由,要想访问192.169.4.0/24,要从192.168.4.1这个口出去,没有下一跳了。因为我右手这个网卡,就是这个网段的,我是最后一跳了。
    于是,路由器B思考的时候,匹配上了这条路由,要从192.168.4.1这个口发出去,发给192.168.4.101。那192.168.4.101的MAC地址是多少呢?路由器B发送ARP获取192.168.4.101的MAC地址,然后发送包。包的内容是这样的:
    • 源MAC:192.168.4.1的MAC地址
    • 目标MAC:192.168.4.101的MAC地址
    • 源IP:192.168.1.101
    • 目标P:192.168.4.101
      包到达服务器B,MAC地址匹配,将包收进来

通过这个过程可以看出,每到一个新的局域网,MAC都是要变的,但是IP地址都不变。在IP头里面,不会保存任何网关的IP地址。所谓的下一跳是,某个IP要将这个IP地址转换为MAC放入MAC头

5.NAT网关

Linux系统编程笔记(12)——网络-萤火
两个IP都是192.168.1.101

这里遇见的一个问题是,局域网之间没有商量过,各定各的网段,因而IP段冲突了。最左面家里的IP地址是192.168.1.101,最右面公司的地址也是192.168.1.101,如果单从IP地址上看,简直就是自己访问自己,其实是从家里的192.168.1.101要访问公司的192.168.1.101。

怎么解决这个问题呢?既然局域网之间没有商量过,你们各管各的,那到国际上,也即是公网里面,就需要使用另外的地址。就像出国,不能用咱们自己的身份证,而要改用护照一样。

首先,目标服务器B在国际上要有一个国际的身份,我们给它一个192.168.56.2。
在网关B上,我们记下来,国际身份192.168.56.2对应国内身份192.168.1.101凡是要访问192.168.56.2,都转成192.168.1.101。于是,源服务器A要访问目标务器B,要指定的目标地址为192.168.56.2。这是它的国际身份。(即做了一个映射,将 192.168.56.2和192.168.1.101绑定起来)

服务器A想,192.168.56.2和我不是一个网段的,因而需要发给网关,网关是谁?已经静态配置好了,网关是192.168.1.1,网关的MAC地址是多少?发送ARP获取网关的MAC地址,然后发送包。包的内容是这样的:

  • 源MAC:服务器A的MAC
  • 目标MAC:192.168.1.1这个网口的MAC
  • 源IP:192.168.1.101
  • 目标IP:192.168.56.2

包到达192.168.1.1这个网口,发现MAC一致,将包收进来。开始思考往哪里转发。在路由器A中配置了静态路由:要想访问192.168.56.2/24,要从192.168.56.1这个口出去,没有下一跳了,因为我右手这个网卡,就是这个网段的,我是最后一跳了。于是,路由器A思考的时候,匹配上了这条路由,要从192.168.56.1这个口发出去,发给192.168.56.2。那192.168.56.2的MAC地址是多少呢?路由器A发送ARP获取192.168.56.2的MAC地址。

当网络包发送到中间的局域网的时候,服务器A也需要有个国际身份,因而在国际上,源IP地址也不能用192.168.1.101,需要改成192.168.56.1(这样别人才可以回信)。发送包的内容是这样的:

  • 源MAC:192.168.56.1这个网口的MAC
  • 目标MAC:192.168.56.2 这个网口的MAC
  • 源IP:192.168.56.1
  • 目标IP:192.168.56.2

包到达192.168.56.2这个网口,发现MAC一致,将包收进来,开始思考往哪里转发。路由器B是一个NAT网关,它上面配置了,要访问国际身份192.168.56.2对应国内身份192.168.1.101,于是改为访问192.168.1.101。在路由器B中配置了静态路由:要想访问192.168.1.0/24,要从192.168.1.1这个口出去,没有下一跳了,因为我右手这个网卡,就是这个网段的,我是最后一跳了。

于是,路由器B思考的时候,匹配上了这条路由,要从192.168.1.1这个口发出去发给192.168.1.101。那192.168.1.101的MAC地址是多少呢?路由器B发送ARP获取192.168.1.101的MAC地址,然后发送包。内容是这样的:

  • 源MAC:192.168.1.1的MAC地址
  • 目标MAC:192.168.1.101的MAC地址
  • 源IP:192.168.56.1
  • 目标IP:192.168.1.101

包到达服务器B,MAC地址匹配,将包收进来。从服务器B接收的包可以看出,源IP为服务器A的国际身份,因而发送返回包的时候,也发给这个国际身份,由路由器A做NAT,转换为国内身份。从这个过程可以看出,IP地址也会变。这个过程用英文说就是Network Address Translation,简称NAT。

可以通过http://www.whatismyip.com/查看自己的出口IP地址
linux抓包工具:tcpdump

Ⅵ. 动态路由算法

1. 路由协议

路由器就是一台网络设备,它有多张网卡。当一个入口的网络包送到路由器时,它会根据一个本地的转发信息库,来决定如何正确地转发流量。这个转发信息库通常被称为路由表。

网络管理员可以手工修改路由表中的路由协议,这种方式叫做静态路由协议。

一般来说网络环境简单的时候,还是可以的。但是有时候网络环境复杂并且多变,如果总是用静态路由,一旦网络结构发生变化,让网络管理员手工修改路由太复杂了,因而需要动态路由算法。

2.动态路由

使用动态路由器,可以根据路由协议算法生成动态路由表,随网络运行状况的变化而变化。那路由算法是什么样的呢?

Linux系统编程笔记(12)——网络-萤火

我们可以将复杂的路径,抽象为一种叫做图的数据结构。至于唐僧西行取经肯定想走的路越少越好,道路越短越好,因而这就转化成为如何在图中找到最短路径的问题。

3.动态路由算法

求最短路径常用的有两种方法,一种是 BelIman-Ford算法,一种是 Dijkstra算法。在计算机网络中基本也是用这两种方法计算的。

第一大类的算法称为距离矢量路由( distance vector routing)。它是基于BelIman-Ford算法的。

这种算法的基本思路是,每个路由器都保存一个路由表,包含多行,每行对应网络中的一个路由器,每一行包含两部分信息,一个是要到目标路由器,从那条线出去,另一个是到目标路由器的距离。由此可以看出,每个路由器都是知道全局信息的。

那这个信息如何更新呢?每个路由器都知道自己和邻居之间的距离,每过几秒,每个路由器都将自己所知的到达所有的路由器的距离告知邻居,每个路由器也能从邻居那里得到相似的信息。每个路由器根据新收集的信息,计算和其他路由器的距离,比如自己的一个邻居距离目标路由器的距离是M,而自己距离邻居是x,则自己距离目标路由器是x+M。

这个算法比较简单,但是还是有问题。

(1)好消息传得快,坏消息传得慢

Linux系统编程笔记(12)——网络-萤火
原先网络中有B和C两个路由器,后来又加入路由器A
Linux系统编程笔记(12)——网络-萤火
有一天,A挂了
Linux系统编程笔记(12)——网络-萤火

以此类推,数越来越大,知道超过某一个阈值,我们才能判定A真的挂了。

(2)每次发送的时候,要发送整个全局路由表

网络大了,谁也受不了,所以最早的路由协议RIP就是这个算法。它适用于小型网络(小于15跳)。当网络规模都小的时候,没有问题。但是现在一个数据中心内部路由器数目就很多,因而不适用了。所以上面的两个问题,限制了距离矢量路由的网络规模。

第二大类算法是链路状态路由( Iink state routing),基于 Dijkstra算法。

这种算法的基本思路是:
当一个路由器启动的时候,首先是发现邻居,向邻居 say hello,邻居都回复。然后计算和邻居的距离,发送一个echo,要求马上返回,除以二就是距离。
然后将自己和邻居之间的链路状态包广播出去,发送到整个网络的每个路由器。这样每个路由器都能够收到它和邻居之间的关系的信息。因而,每个路由器都能在自己本地构建一个完整的图,然后针对这个图使用 Dijkstra算法,找到两点之间的最短路径。

不像距离距离矢量路由协议那样,更新时发送整个路由表。链路状态路由协议只广播更新的或改变的网络拓扑,这使得更新信息更小,节省了带宽和CPU利用率。而且ー旦ー个路由器挂了,它的邻居都会广播这个消息,可以使得坏消息迅速收敛。

4.动态路由协议

(1)基于链路状态路由算法的OSPF(Open Shortest Path First,开放式最短路径优先)就是这样一个基于链路状态路由协议,广泛应用在数据中心中的协议。由于主要用在数据中心内部,用于路由决策,因而称为内部网关协议(Interior Gateway Protocol,简称IGP)。

内部网关协议的重点就是找到最短的路径。在一个组织内部,路径最短往往最优。当然有时候OSPF可以发现多个最短的路径,可以在这多个路径中进行负载均衡,这常常被称为等价路由。

(2)BGP协议

BGP协议使用的算法是路径矢量路由协议(path-vector protocol)。它是距离矢量路由协议的的升级版。

BGP是自治系统间的路由协议,BGP交换的网络可达性信息提供了足够的信息来检测路由回路并根据性能优先和策略约束对路由进行决策