大师兄

加餐 | 模块二思考题解答

今天我会带你把《模块二:网络层协议》中涉及的课后练习题,逐一讲解,并给出每个课时练习题的解题思路和答案。

06 | IPv4 协议:路由和寻址的区别是什么?

问题下面这几个地址 127.0.0.1, localhost, 0.0.0.0 有什么不同

解析127.0.0.1是本地回环地址(loopback),发送到 loopback 的数据会被转发到本地应用。

localhost 指代的是本地计算机,用于访问绑定在 loopback 上的服务。localhost 是一个主机名,不仅仅可以指向 IPv4 的本地回环地址,也可以指向 IPv6 的本地回环地址 [::1]。

0.0.0.0是一个特殊目的 IP 地址,称作不可路由 IP 地址,它的用途会被特殊规定。通常情况下,当我们把一个服务绑定到0.0.0.0,相当于把服务绑定到任意的 IP 地址。比如一台服务器上有多个网卡,不同网卡连接不同的网络,如果服务绑定到 0.0.0.0 就可以保证服务在多个 IP 地址上都可以用。

07 | IPv6 协议:Tunnel 技术是什么?

问题请你总结下 IPv6 和 IPv4 究竟有哪些区别

解析】IPv6 和 IPv4 最核心的区别是地址空间大小不同。IPv6 用 128 位地址,解决了 IP 地址耗尽问题。因为地址空间大小不同,它们对地址的定义,对路由寻址策略都有显著的差异。

在路由寻址策略上,IPv6 消除了设备间地址冲突的问题,改变了划分子网的方式。在 IPv4 网络中,一个局域网往往会共享一个公网 IP,因此需要 NAT 协议和外网连接。

在划分子网的时候,IPv4 地址少,需要子网掩码来处理划分子网。IPv6 有充足的地址,因此不需要局域网共享外网 IP。也正因为 IPv6 地址多,可以直接将 IPv6 地址划分成站点、子网、设备,每个段都有充足的 IP 地址。

因为 IPv6 支持的 IP 地址数量大大上升,一个子网可以有 248 个 IP 地址,这个子网可能是公司网络、家庭网络等。这样 IP 地址的分配方式也发生了变化,IPv4 网络中设备分配 IP 地址的方式是中心化的,由 DHCP(动态主机协议)为局域网中的设备分配 IP 地址。而在 IPv6 网络中,因为 IP 地址很少发生冲突,可以由设备自己申请自己的 IP 地址。

另外因为 IPv6 中任何一个节点都可以是一个组播节点,这样就可以构造一个对等的网络,也就是可以支持在没有中心化的路由器,或者一个网络多个路由器的情况下工作。节点可以通过向周围节点类似打探消息的方式,发现更多的节点。这是一个配套 IPv6 的能力,叫作邻居发现(ND)。

08 | 局域网:网络地址转换是如何工作的?

问题IPv6 协议还需要 NAT 吗?

解析】IPv6 解决了 IP 耗尽的问题,为机构、组织、公司、家庭等网络提供了充足的 IP 资源,从这个角度看是不是就不需要 NAT 协议了呢?

在没有 IPv6 之前,NAT 是 IP 资源耗尽的主流解决方案。在一个内网中的全部设备通过 NAT 协议共享一个外网的 IPv4 地址,是目前内外网对接的主要方式。IPv6 地址资源充足,可以给全球每个设备一个独立的地址。从这个角度看 IPv6 的确不需要 NAT 协议。

但是目前的情况,是 IPv6 网络还没有完全普及。尽管很多公司已经支持自己的互联网产品可以使用 IPv6 访问,但是公司内部员工使用的内部网络还是 IPv4。如果要连接 IPv6 和 IPv4 网络,仍然需要 NAT 协议(NAT64),这个协议可以让多个 IPv6 的设备共享一个 IPv4 的公网地址。

09 | TCP 实战:如何进行 TCP 抓包调试?

【问题请你用自己最熟悉的语言,写一个 UDP 连接程序,然后用 Wireshark 抓包

解析】关于这个实战问题,我以 Java 为例,写了一个回声服务(即客户端发送什么服务段返回什么),以下是服务端程序:

var socket = new DatagramSocket(8888);
var buf = new byte[256];
while (true) {
    DatagramPacket packet
            = new DatagramPacket(buf, buf.length);
    System.out.println("try receive...");
    socket.receive(packet);
    var address = packet.getAddress();
    int port = packet.getPort();
    packet = new DatagramPacket(buf, buf.length, address, port);
    String received
            = new String(packet.getData(), 0, packet.getLength());
    socket.send(packet);
}

以下是客户端程序:

var buf = "Hello".getBytes();
  var socket = new DatagramSocket();
  var address = InetAddress.getByName("localhost");
  var packet
          = new DatagramPacket(buf, buf.length, address, 8888);
  socket.send(packet);
  socket.receive(packet);
  String received = new String(
          packet.getData(), 0, packet.getLength());
  System.out.format("Server echo : %s\n", received);

通过观察上面两段程序,你会发现发送和接收的都是Datagram报文。而且服务端和客户端之间不需要建立连接。服务端可以通过读取客户端的地址区分客户端,客户端通过服务端地址和端口发送数据到服务端。

总结

这个模块我们围绕局域网和 IP 协议展开,包括 ARP、IPv4、IPv6、NAT 等基本概念,探讨了 IPv6 的工作原理,以及 IPv6 和 IPv4 的兼容策略。IP 协议几乎是网络层的唯一协议,因此是大厂面试最为热门的内容之一。

你可以通过以下几个维度去理解这部分知识:

  1. 最底层设备如何向设备发送信息(MAC 地址、路由器、ARP 协议等)?

  2. 小型局域网是怎样工作的(交换机和路由器)?

  3. 中型局域网如何工作的?

  4. 局域网如何对接外网(NAT)?

  5. 互联网中如何定位设备和网络(IP 协议的路由和寻址是如何工作的)?

通过上面这样的一个分层的总结,你可以逐层分析下自己是否已经理解了这个模块最核心的内容。这部分知识最大的价值在于平时在遇到网络问题时,可以找到一些思考方向。比如说为什么部分产品要解决 NAT 穿透的问题?网吧的用户会遇到什么问题?为什么你 Ping 不通同一个局域网的另一台机器?

到这里,传输层协议和网络层协议就介绍完了,它们是计算机网络最底层的基础知识,建议你踏实学习,打好基础。

发现求知的乐趣,我是林䭽,感谢你学习本次课程。 接下来我们将进入《模块三:网络编程》的学习,下一讲介绍“10 | Socket 编程:epoll 为什么用红黑树?”,再见!