9.3. 线缆与帧¶
在摄像头上,协议栈最底下的两层最容易被人们视为理所当然,因为它们所做的一切都发生在芯片内部,摄像头会自行处理,无需任何 Python 代码参与。但它们仍然值得简要了解一番,因为它们解释了"本地网络"的含义,以及与其余基础设施之间的边界从何处开始。
9.3.1. 物理层¶
最底层是实际的信号传输——承载着两台设备之间比特位的电线、光纤或无线电波。基于双绞线的以太网将每个比特位以固定速率编码为电压跳变。Wi-Fi 则将相同的比特位调制到 2.4 GHz 或 5 GHz 频段的无线电载波上。两者都在两个硬件之间产生一串二进制数字;两者都属于摄像头硅芯片会自行处理、软件无需操心的那类细节。
从 Python 脚本的角度来看,物理层无非就是"链路已连通"或"链路已断开"。network 模块通过 Wi-Fi 接口上的 isconnected() 方法以及有线以太网接口上的链路状态来报告这一状态。除此之外,这一层所做的其他一切都是隐藏的。
9.3.2. 链路层¶
再往上一层是链路层——在共享同一物理网段的两台设备之间发送一块字节(即一个帧)的规则。链路层在原始信号传输之上增加了两样东西:
硬件寻址。 每个网络接口都自带一个唯一的 48 位标识符,称为 MAC 地址(Media Access Control,介质访问控制)。在以太网上它被固化在芯片中;在 Wi-Fi 上它是同类标识符,固化在无线模块中。MAC 地址是交换机——那个带有多个以太网端口、供附近设备插入的盒子——用来决定某个帧应该从哪个端口发出的依据。Wi-Fi 接入点对其信道上的无线设备扮演着同样的角色。
成帧。 上层交下来的字节被打包成一个帧,帧由一个小的帧头、负载和末尾的校验和组成。帧头携带源 MAC 地址和目标 MAC 地址;校验和让接收方能够检测出在传输途中字节遭到损坏的帧。未通过校验的帧会被悄悄丢弃——谁在意可靠性,谁就得在更高的层级把它补回来。
本地网段是指任何能够直接看到彼此帧的设备组——一台交换机上的有线端口、关联到同一个 Wi-Fi 接入点的所有设备,或者由若干互联交换机组成的小型网状结构。链路层无法触及该网段之外的范围。一旦目标位于不同的网段,消息就必须交给上一层来处理。
9.3.3. 摄像头所暴露的内容¶
摄像头为它拥有的每个网络接口都配有一个 MAC 地址——如果摄像头支持无线,就有一个 Wi-Fi 的;如果开发板带有相应端口,就有一个以太网的。当需要读取该地址时,network 模块通过应用所使用的接口对象上的 network_interface.config("mac") 来提供访问。某些应用确实需要这样做,例如把设备注册到一个机群管理系统中。除此之外,这是链路层交给 Python 处理的唯一旋钮。
其余的一切——成帧、电缆或空中实际的 MAC 流量、摄像头与接入点之间关于使用哪个信道和速率的协商——全都完全发生在无线或以太网硬件内部。下一页 介绍了 Python 脚本在链路层中确有发言权的唯一一处:告诉摄像头要加入哪个网络。