Closed FrankKai closed 3 years ago
只有通过这种协议,计算机才知道我们想让它做什么。
只有通过网络协议,才能使一大片机器互相协作、共同完成一件事。
网关是一个路由器,通过路由表,知道到某个IP怎么走。 通过网卡的MAC地址,可以唯一定位目标服务器,也可以唯一定位客户端电脑。
目标服务器发现 MAC 地址对上了,取下 MAC 头来,发送给操作系统的网络层。发现 IP 也对上了,就取下 IP 头。IP 头里会写上一层封装的是 TCP 协议,然后将其交给传输层,即TCP层。
在TCP层里,对于收到的每个包,都会有一个回复的包说明收到了。这个回复的包绝非这次下单请求的结果,例如购物是否成功,扣了多少钱等,而仅仅是 TCP 层的一个说明,即收到之后的回复。当然这个回复,会沿着刚才来的方向走回去,报个平安。 如果过一段时间还是没到,发送端的 TCP 层会重新发送这个包,还是上面的过程,直到有一天收到平安到达的回复。 这个重试绝非你的浏览器重新将下单这个动作重新请求一次。对于浏览器来讲,就发送了一次下单请求,TCP 层不断自己闷头重试。除非 TCP 这一层出了问题,例如连接断了,才轮到浏览器的应用层重新发送下单请求。
网络包到达TCP层之后,TCP头中有目标端口号,通过这个端口号,可以找到电商网站监听此端口号的进程,而这个监听者,就可能是Tomcat
云计算,容器,微服务等。例如Docker,kubernetes,microServies等等。
二层设备、三层设备、四层LB和七层LB中层
为什么网络要分层呀?因为不同的层次之间有不同的沟通方式,这个叫作协议。例如,一家公司也是分“层次”的,分总经理、经理、组长、员工。总经理之间有他们的沟通方式,经理和经理之间也有沟通方式,同理组长和员工。
send_layer2(buffer),这个函数里面要加一下 MAC 的头,记录下 MAC 地址,得到的就是本机器的 MAC 地址和目标的 MAC 地址或者网关MAC。
加了HTTP头和内容,TCP的头,IP的头以及MAC头之后,称为一个完整的Buffer之后,才能从网口发出去。
TCP每发送一个消息,都会带着IP层和MAC层。因为TCP每发送一个消息,IP层和MAC层的所有机制都要运行一遍。对于TCP协议来说,三次握手也好,重试也好,只要想发出去包,就要有IP层和MAC层,不然是发不出去的。
云学:通信协议就像没有天桥的双子楼,要从A座的24层到达B座24层就得先下楼梯再上楼梯,其他协议也是如此,比如4G
ip addr
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
1. LOOPBACK,UP,LOWER_UP,BROADCAST,MULTICAST什么意思? 这个叫做net_device flags,是网络设备的状态标识。
net_device flag | 含义 |
---|---|
LOOPBACK | lo全称是loopback,又称环回接口,往往会被分配到 127.0.0.1 这个地址。这个地址用于本机通信,经过内核处理后直接返回,不会在任何网络中出现。 |
UP | 网卡处于启动状态 |
LOWER_UP | L1是启动的,也就是网线是插着的 |
BROADCAST | 表示网卡有广播地址,可以发送广播包 |
MULTICAST | 网卡可以发送多播包 |
2. mtu 65536和mtu 1500是什么意思? MTU是二层MAC层的概念,MAC层有MAC头,以太网规定连MAC头带正文合起来,不允许超过1500个字节。正文中包括三层的IP头,四层的TCP头以及五层的HTTP头。如果放不下,就需要用分片来传输。
3. qdisc noqueue、qdisc pfifo_fast是什么意思? qdisc的全称是queueing discipline,中文叫排队规则。内核如何需要通过网络接口发送数据包,它都需要按照为这个接口配置的qdisc(排队规则)把数据包加入队列。 最简单的qdisc是pfifo,不对进入的数据包做任何处理,数据包采用先入先出方式通过队列。 pfifo_fast稍微复杂一些,它的队列包括三个波段(band),每个波段中先入先出。band0优先级最高。在波段中,包也有优先级,数据包是按照TOS(Type of Service)分配的,TOS是三层IP头里面的一个字段,代表数据包的优先级。 队列在云计算的网络中,会有很多用户共享一个网络出口的情况,这个时候如何排队,每个队列有多粗,队列处理速度如何提升,都是非常有趣的。
4. 公有IP地址和私有IP地址 我们继续看上面的表格。表格最右列是私有 IP 地址段。平时我们看到的数据中心里,办公室、家里或学校的 IP 地址,一般都是私有 IP 地址段。因为这些地址允许组织内部的 IT 人员自己管理、自己分配,而且可以重复。因此,你学校的某个私有 IP 地址段和我学校的可以是一样的。 这就像每个小区有自己的楼编号和门牌号,你们小区可以叫 6 栋,我们小区也叫 6 栋,没有任何问题。但是一旦出了小区,就需要使用公有 IP 地址。就像人民路 888 号,是国家统一分配的,不能两个小区都叫人民路 888 号。 公有 IP 地址有个组织统一分配,你需要去买。如果你搭建一个网站,给你学校的人使用,让你们学校的 IT 人员给你一个 IP 地址就行。但是假如你要做一个类似网易 163 这样的网站,就需要有公有 IP 地址,这样全世界的人才能访问。 表格中的 192.168.0.x 是最常用的私有 IP 地址。你家里有 Wi-Fi,对应就会有一个 IP 地址。一般你家里地上网设备不会超过 256 个,所以 /24 基本就够了。有时候我们也能见到 /16 的 CIDR,这两种是最常见的,也是最容易理解的。 不需要将十进制转换为二进制 32 位,就能明显看出 192.168.0 是网络号,后面是主机号。而整个网络里面的第一个地址 192.168.0.1,往往就是你这个私有网络的出口地址。例如,你家里的电脑连接 Wi-Fi,Wi-Fi 路由器的地址就是 192.168.0.1,而 192.168.0.255 就是广播地址。一旦发送这个地址,整个 192.168.0 网络里面的所有机器都能收到。
5. CIDR是什么? 由于32位的IP地址不够用,所以讲将32位IP地址一分为二,前面是网络号,后面是主机号。 伴随着CIDR的,还有广播地址10.100.122.255,所有10.100.122网络里面的机器都可以收到。子网掩码255.255.255.0。 为什么10.100.122网络里的所有机器都可以收到呢?网络号,子网掩码与IP地址进行AND运算得到。255转成二进制都是1,1与任何数与运算都为1,0与任何数与运算都为0,因此得到网络号。
6. inet 127.0.0.1/8 scope host lo、inet 10.100.122.2/24 brd 10.100.122.255 scope global eth0什么意思?
inet 127.0.0.1/8 scope host lo
127.0.0.1这个地址用于本机通信,经过内核处理后直接返回,不会在任何网络中出现。127.0.0.1/8是一种CIDR的地址表示形式,/8表示前8位是网络号,后24位是主机号。scope host lo的意思是,对于lo这张网卡来说,当前网卡的scope是host,也就是说这张网卡仅仅可以供本机相互通信。
inet 10.100.122.2/24 brd 10.100.122.255 scope global eth0
也是CIDR,对于eth0这张网卡来说,是global,说明这张网卡是可以对外的,可以接收来自各个地方的包。10.100.122.2/24,意思是前24位是网络号,8位是主机号,也就是10.100.122.x,这里的x代表主机号,2的8次方等于256,我们的机器从10.100.122.2一直到10.100.122.254,可以有253台,这里的机器获得的都是私有IP地址。
为什么10.100.122.0,10.100.122.1,10.100.122.255不能作为我们的机器?
我们这里的10.100.122.2也是私有网络的出口地址,可以与通过10.100.122.0与外界机器进行通信,也可以通过10.100.122.255与局域网内机器进行通信。
公有ip查询:https://www.ip.cn/
私有ip查询:ifconfig
公有ip:
您现在的 IP:115.204.91.5
所在地理位置:浙江省杭州市 电信
GeoIP: Hangzhou, Zhejiang, China
私有ip:
192.168.0.46
公有ip:
您现在的 IP:115.204.91.5
所在地理位置:浙江省杭州市 电信
GeoIP: Hangzhou, Zhejiang, China
私有ip:
192.168.0.58
这个是MAC地址,是一个网卡的物理地址,用16进制,6个byte表示。 MAC 地址号称全局唯一,不会有两个网卡有相同的 MAC 地址。 一个网络包要从一个地方传到另一个地方,除了要有确定的地址,还需要有定位功能。而有门牌号码属性的 IP 地址,才是有远程定位功能的。 MAC 地址更像是身份证,是一个唯一的标识。它的唯一性设计是为了组网的时候,不同的网卡放在一个网络里面的时候,可以不用担心冲突。从硬件角度,保证不同的网卡有不同的标识。 MAC地址不能定位吗? MAC地址有一定定位功能,只不过范围有限,当根据IP定位到一定范围时,再根据MAC地址,才能找到精确的一台机器,如果没根据IP进入到这个区域,只根据MAC地址找是无效的。 MAC地址的通信范围比较小,仅仅局限在一个子网里面。 192.168.0.2/24访问192.168.0.3/24 ✔️ 192.168.0.2/24访问192.168.1.2/24 ❌因为跨越了子网,不仅需要MAC地址,还需要IP地址起作用。
en0是私有ip有线网卡,en1是私有ip无线网卡。
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=10b<RXCSUM,TXCSUM,VLAN_HWTAGGING,AV>
ether 78:7b:8a:d7:76:1e
inet6 fe80::1073:cbb2:b1a8:1efa%en0 prefixlen 64 secured scopeid 0x6
inet 192.168.0.46 netmask 0xffffff00 broadcast 192.168.0.255
nd6 options=201<PERFORMNUD,DAD>
media: autoselect (1000baseT <full-duplex,flow-control>)
status: active
en1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
ether 14:20:5e:00:b3:8c
inet6 fe80::105c:2fa7:999b:50bf%en1 prefixlen 64 secured scopeid 0x7
inet 169.254.214.195 netmask 0xffff0000 broadcast 169.254.255.255
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
$ sudo ifconfig eth1 10.0.0.1/24
$ sudo ifconfig eh1 up
$ sudo ip addr add 10.0.0.1/24 dev eth1
$ sudo ip link set up eth1
假设自己的机器想配置成192.168.1.46,结果配置成了10.23.42.1。 现在从192.168.1.46去ping 192.168.1.6。 配置错了会有什么影响? 发不出去包。 为什么发不出去包? Linux系统需要判断,只要网络上的包,都是完整的,可以有下层没上层,但是绝对不可以没有上层没下层。有源IP地址10.23.42.1,也有目标IP地址192.168.1.6,但是由于MAC层没填,所以发不出去。
源MAC地址可以获取,目标MAC地址呢? 是192.168.1.6的MAC地址吗?不是。Linux会判断是否在一个网段,只有在一个网段,才会发送ARP请求,从而获取到MAC地址。 Linux发现目标机器和自己不在一个网段怎么办? Linux默认的逻辑是,如果这是一个跨网段的调用,它便不会直接将包发送到网络上,而是企图将包发到网关。 若是跨网段发包,会怎么发呢?
由于这是一个跨网段调用,源IP和目标IP虽然正确,但是目标MAC地址是网关的MAC地址对不上号,因此发不成功。
IP: 10.23.42.1->192.168.1.6
MAC: 10.23.42.1本地MAC->10.23.42.1网关MAC(并不是预期的192.168.1.6的本地MAC)
所以,如果需要手动配置一台机器的网络IP,需要问清楚网管正确的IP地址。一般来说是在配置文件中,其中包括:CIDR、子网掩码、广播地址和网关地址。
这是一个不用IT人员配置电脑IP的技术,大大解放配置IP的生产力。
总结一下:
其实一台机器加入到一个新的网络,然后DHCP Server为其分配IP地址的过程,非常类似于一个大牛求职者求职的过程,当这个大牛有换个坑的意向时,各种猎头会来联系他,瞬间他就会拥有很多面试,并且选择感兴趣的几家去面试,不出意外的话,在这之后,他会收获到很多Offer,在经过一番认真思考过后,他会选择其中一家的Offer,并且告诉其他公司"有机会再一起合作"。
IP续租前和租房子一样,需要提前告诉DHCP Server。 客户机在什么时候发起续租申请? 在租期过去50%的时候,向DHCP Server发送DHCP request,DHCP Server返回DHCP ACK消息包,其中包含新租期和其他TCP/IP参数,更新配置,IP租用更新完成。
闻所未闻:网络管理员不仅能自动分配IP地址,还能帮我们安装操作系统!
PXE客户端若想知道PEX服务器端的IP地址,需要在DHCP Server中指明:
ddns-update-style interim;
ignore client-updates;
allow booting;
allow bootp;
subnet 192.168.1.0 netmask 255.255.255.0
{
option routers 192.168.1.1;
option subnet-mask 255.255.255.0;
option time-offset -18000;
default-lease-time 21600;
max-lease-time 43200;
range dynamic-bootp 192.168.1.240 192.168.1.250;
filename "pxelinux.0";
next-server 192.168.1.180;
}
PXE客户端访问PXE服务器端的额外配置:
next-server:指向PXE服务器的地址
filename:初始启动文件
这些问题都是二层,即数据链路层,MAC(Medium Access Control,媒体访问控制)层解决的问题。
控制谁先发,谁后发的问题,防止发生混乱。专业名称叫多路访问。
多路访问的几种实现方式
这时需要用到一个物理地址,叫做链路层地址,但是因为第二层主要解决媒体接入控制,因此也这个地址也叫MAC地址,这也是第二层叫MAC层的主要原因。
1.目标机器MAC网卡发现数据包,接收MAC包 2.打开IP包,发现IP是自己 3.打开TCP包,发现端口也是自己,80 4.nginx监听80,nginx返回网页 ARP协议也解决了"发给谁,谁接收"的问题。
CRC,循环冗余检测。
已知:源IP地址,源MAC地址,目标IP地址 未知:目标MAC地址 假设192.168.0.23与192.168.0.46通信,23发送一个广播包,46谁来回答。
交换机(可以将MAC头拿下来,检查一下目标MAC地址,根据策略转发的设备)
一段时间之后,交换机会准确记住所有机器的MAC地址,基本不用广播,精确转发网络包。但是因为机器IP会变,因此交换机的转发表有过期时间,这与IP-MAC映射表类似。
一般来说,公司里会有很多机器,每台机器对应一个网口,少则几十台,多则几百台,上千上万台,此时一个交换机就不够用了,需要多台交换机,交换机之间连接起来,就形成了一个复杂的拓扑结构。
一个完整的ARP请求过程: 机器1在LAN1广播->交换机A转发消息到LAN2->交换机B在LAN3广播->机器4收到广播消息并返回MAC地址 笔记:交换机在开始时不知道任何拓扑信息,因此接到消息都是以广播的形式发送。
经过一次ARP请求之后,交换机A和B会记住机器一所属的局域网,当机器2访问机器1的时候,交换机A不会再把消息广播到LAN2和LAN3。当机器3给机器1发送ARP请求的时候,交换机B由于知道机器1在LAN1,所以不会在LAN3进行广播,交换机A会在LAN1中广播。
计算机网络中的生产树算法,叫做STP,全称Spanning Tree Protocol。
STP 协议,将有环路的图变成没有环路的树,解决网络包迷路问题。
物理隔离,独立的交换机。 虚拟隔离,VLAN,虚拟局域网,二层上加VLAN ID。
可以直接ping一个域名,通过本地的hosts文件进行DNS映射。
192.168.0.144 -> 192.168.0.111
ping 192.168.0.111
PING 192.168.0.111 (192.168.0.111): 56 data bytes
64 bytes from 192.168.0.111: icmp_seq=0 ttl=64 time=0.565 ms
64 bytes from 192.168.0.111: icmp_seq=1 ttl=64 time=0.599 ms
64 bytes from 192.168.0.111: icmp_seq=2 ttl=64 time=0.567 ms
64 bytes from 192.168.0.111: icmp_seq=3 ttl=64 time=0.581 ms
64 bytes from 192.168.0.111: icmp_seq=4 ttl=64 time=0.587 ms
64 bytes from 192.168.0.111: icmp_seq=5 ttl=64 time=0.557 ms
64 bytes from 192.168.0.111: icmp_seq=6 ttl=64 time=0.566 ms
^C
--- 192.168.0.111 ping statistics ---
7 packets transmitted, 7 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.530/0.604/0.877/0.094 ms
1.发送了7个icmp主动探查包,全部接收到。 2.ttl=64代表什么?time to live,IPv4协议下,TTL是20的第9个八位字节。在IPv6标头中,它是40的第8个八位字节,建议的初始TTL值为64。 3.time是什么意思?应答包到达时间 - 探查包发出时间,min,avg,max,stddev(标准差)。
192.168.0.144 -> 192.168.0.146
ping 192.168.0.146
PING 192.168.0.146 (192.168.0.146): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4
Request timeout for icmp_seq 5
Request timeout for icmp_seq 6
^C
--- 192.168.0.146 ping statistics ---
7 packets transmitted, 0 packets received, 100.0% packet loss
0~6就是ping主动探查ICMP报文的顺序号,发送了8个ICMP请求网络包,没有一个到达,100丢包率。
192.168.0.144对网卡en0开启监听,tcpdump -i en0 icmp
。
crm.test.weidiango.com(192.168.0.146)发起ping请求,ping 192.168.0.144
。
tcpdump -i en0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:56:00.779712 IP crm.test.weidiango.com > 192.168.0.144: ICMP echo request, id 1, seq 1, length 40
14:56:00.779808 IP 192.168.0.144 > crm.test.weidiango.com: ICMP echo reply, id 1, seq 1, length 40
14:56:01.782639 IP crm.test.weidiango.com > 192.168.0.144: ICMP echo request, id 1, seq 2, length 40
14:56:01.782712 IP 192.168.0.144 > crm.test.weidiango.com: ICMP echo reply, id 1, seq 2, length 40
14:56:02.790405 IP crm.test.weidiango.com > 192.168.0.144: ICMP echo request, id 1, seq 3, length 40
14:56:02.790463 IP 192.168.0.144 > crm.test.weidiango.com: ICMP echo reply, id 1, seq 3, length 40
14:56:03.798310 IP crm.test.weidiango.com > 192.168.0.144: ICMP echo request, id 1, seq 4, length 40
14:56:03.798367 IP 192.168.0.144 > crm.test.weidiango.com: ICMP echo reply, id 1, seq 4, length 40
8 packets captured
6554 packets received by filter
0 packets dropped by kernel
ping 192.168.0.144
64 bytes from 192.168.0.144: icmp_seq=0 ttl=64 time=0.565 ms
64 bytes from 192.168.0.144: icmp_seq=1 ttl=64 time=0.599 ms
64 bytes from 192.168.0.144: icmp_seq=2 ttl=64 time=0.567 ms
64 bytes from 192.168.0.144: icmp_seq=3 ttl=64 time=0.581 ms
...
知识点:
tcpdump -i en0 <protocol>
这里的协议可以是udp, tcp, icmp, ip, arp, vlan, stp等等,但不能是https, http, rpc等等。 当不填协议类型时,将会监听到所有的当前网卡的网络包。
Gateway知识点
不能,虽然都是192.168.1.x,都被家用路由器NAT成了运营商的地址了。
当然是公网IP贵,这个可以被很多人访问到。但是私网IP仅仅被办公室或者实验室里的人访问到。所以办公室一般只要一到两个出口IP地址。
ip route add 10.176.48.0/20 via 10.173.32.1 dev eth0
就说明要去 10.176.48.0/20 这个目标网络,要从 eth0 端口出去,经过 10.173.32.1。
除IP地址外,根据入口设备、TOS等选择路由表。
ip rule add from 192.168.1.0/24 table 10
ip rule add from 192.168.2.0/24 table 20
从 192.168.1.10/24 这个网段来的,使用 table 10 中的路由表,而从 192.168.2.0/24 网段来的,使用 table20 的路由表。
还可以按走多路由:
ip route add default scope global nexthop via 100.100.100.1 weight 1 nexthop via 200.200.200.1 weight 2
下一跳可以是两个地方,100.100.100.1和200.200.200.1,权重分别是1和2.
房东太良心,拉了两个运营商的宽带,因此家里的路由器也换成了可以接2个外网的路由器,一个网速快,一个网速慢。(租房的小伙伴们,如果房东再跟你说家里网速慢没法解决,你可以用处这一招,电信,移动,联通统统接进来。当然,最好是自己买房。)
$ ip route list table main
60.190.27.189/30 dev eth3 proto kernel scope link src 60.190.27.190
183.134.188.1 dev eth2 proto kernel scope link src 183.134.189.34
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.1
127.0.0.0/8 dev lo scope link
default via 183.134.188.1 dev eth2
路由器规则:
若有用户仅仅上个网页,网费便宜一点,怎么办? 1.添加新路由表
# echo 200 chao >> /etc/iproute2/rt_tables
2.添加规则,让新来的路由表都走新路由表
# ip rule add from 192.168.1.101 table chao
# ip rule ls
0: from all lookup local
32765: from 10.0.0.10 lookup chao
32766: from all lookup main
32767: from all lookup default
3.默认路由走慢的
# ip route add default via 60.190.27.189 dev eth3 table chao
# ip route flush cache
最短路径的两种算法:
distance vector routing,基于Bellman-Ford算法。 关键信息:目标路由器,到目标路由器的距离。
问题1:好消息传的快,坏消息传的慢(hhhhhhhhh,这个图也太逗了。 问题2:每次发送,都要发送整个全局路由表 早期路由协议RIP就是这个算法,适用于小于15跳的小型网络。
所以距离矢量路由算法的最大问题是:限制了网络的规模。
link state routing,基于Dijkstra算法。 这种算法采用的是广播的方式,类似事件发布订阅的方式。 算法基本思路是:路由器启动,发现邻居,然后echo,邻居回复,计算出距离,然后将当前路由与邻居间的链路状态包广播出去,发送到整个路由器的每个路由器。这样每个路由器都对整个网络的宏状态有很清晰的认识,利用这个图,再使用Dijkstra算法,找出两点间最短路径。
这种算法与异步思想契合,更新只要发送广播更新的或者改变的拓扑,非常节省带宽和CPU利用率。
总结:
能分享下pdf文档么? 我在英国 国内的网站下载动不动就要金币之类的 感觉不靠谱。。。
老师的GitHub是哪个呀?他说写了一个实验教程放到GitHub上,但是我没找到
在极客时间上订阅了刘超老师的《趣谈网络协议》专栏,在这个issue中,我将按照专栏文章章节,摘取自己认为比较重要的网络协议知识点,并且写一些自己的看法。