串行编程/串行连接上的 IP
串行编程: 介绍和 OSI 网络模型 -- RS-232 布线和连接 -- 典型的 RS232 硬件配置 -- 8250 UART -- DOS -- MAX232 驱动器/接收器系列 -- Windows 中的 TAPI 通信 -- Linux 和 Unix -- Java -- Hayes 兼容调制解调器和 AT 命令 -- 通用串行总线 (USB) -- 形成数据包 -- 错误校正方法 -- 双向通信 -- 数据包恢复方法 -- 串行数据网络 -- 实际应用开发 -- 串行连接上的 IP
本页假设读者熟悉 TCP/IP 协议族和一般的 IP 通信。
本模块使用正常的 TCP/IP 术语,其中术语表示以下内容
- TCP
- TCP 协议本身,在传输层。
- IP
- IP 协议本身,在互联网层。
- TCP/IP
- 完整的互联网协议族,包括比 TCP 或 IP 更多的协议。
此外,本模块使用 TCP/IP 的协议层符号,而不是 OSI 模型,除非另有说明。
+--------------------+ | Application Layer | e.g. SMTP +--------------------+ | Transport Layer | e.g. TCP +--------------------+ | Internetwork Layer | e.g. IP +--------------------+ | Link Layer | e.g. SLIP or PPP +--------------------+
通过串行 (RS-232) 线传输 IP 数据会遇到一些问题,其中包括:
- 缺少帧
- 缺少流量控制
- 缺少会话管理
其中缺少帧是最严重的问题。所有提到的问题都将解释如下。
不同的层在 TCP/IP 协议栈中承担不同的任务。上层协议期望下层协议提供特定的服务。IP 协议期望链路层提供的服务之一是 IP 数据包的帧和去帧。这意味着,链路层负责在数据包通过通信链路时正确分离每个数据包并识别 IP 数据包的开始和结束。链路层应该这样做,以便在将数据包放置在某个数据流中时,可以正确地从数据流中提取它们。
在使用“裸”串行连接作为链路层的情况下,会产生一个问题,因为简单的串行连接不提供任何帧功能。相反,数据只是一个流。接收方将无法明确识别数据包的开始和结束。
在 100% 可靠的串行连接中,这可以容忍,因为 IP 数据包中的长度信息可以用来将数据包从串行数据流中分离出来。但是,连接通常不是 100% 可靠的,特别是如果它是通过调制解调器在公共电话线上进行的。如果数据包被损坏、部分丢失等,接收方将失去同步,传输将完全混乱。如果可以可靠地识别损坏的 IP 数据包,TCP 等上层协议可以处理问题并启动重新传输。因此,正确识别,以及 IP 数据包的帧/去帧是必不可少的。
由于串行连接的性质,需要对串行连接跃点进行流量控制。但是,IP 没有提供任何在链路层控制流量的机制,TCP 等协议使用完全不同的方式进行端到端流量控制,并且根本不处理单个跃点。
在串行线上运行 IP 时,通常需要做一些额外的“管理工作”,特别是当该串行线由调制解调器连接支持时。这包括建立这样的调制解调器连接(拨号到某个远程站点)并在该远程站点进行身份验证。IP 本身不支持这些任务。
解决上述问题的办法是在链路层引入一个额外的协议。该协议实际上代表了上层协议的链路层,并在内部使用串行连接。
目前常用的协议有两种。一种非常简单的协议叫 SLIP,另一种更复杂但更强大的协议叫 PPP。新服务通常使用 PPP,而 SLIP 仍然可以在一些旧服务中找到。
+-------------+ | TCP | +-------------+ | IP | +-------------+---------------+ | Link Layer | Modem Control | +-------------+---------------+ | Serial Line | +-----------------------------+ | Modem | +-----------------------------+ | Phone Line | +-----------------------------+
SLIP 解决了将 IP 数据报发送到串行线上的一个最严重的问题:缺乏帧定界。流量控制由调制解调器传输协议和更高级别的 TCP/IP 协议处理。会话管理应该在 SLIP 之外处理,例如调制解调器连接的设置(“拨号”)不是由 SLIP 完成的。SLIP 假设串行连接已经建立。
SLIP 在 RFC 1055 中进行了标准化,标题为 *通过串行线路传输 IP 数据报的非标准方法:SLIP*。标题中的 *非标准* 一词源于历史原因。SLIP 很久以来都没有被描述,直到它最终在 RFC 1055 中被描述,这个描述仅仅是作为对当时实践情况的非正式总结。直到后来才决定将该 RFC 赋予 IETF 官方标准的地位,但由于 SLIP 的局限性,它不应该成为首选。
SLIP 非常简单,几乎令人尴尬。它需要 8 位数据位、无奇偶校验和硬件流控制或 CLOCAL 模式(3 线空闲模式)的串口配置。它只定义了四个特殊的 8 位序列(字符)和很少的功能,超过了标准的串行线路协议。
十六进制值 | 八进制值 | 缩写 | 描述 |
---|---|---|---|
0xC0 | 0300 | END | 帧结束 |
0xDB | 0333 | ESC | 转义 |
0xDC | 0334 | ESC_END | 转置的帧结束符,在转义序列中使用 |
0xDD | 0335 | ESC_ESC | 转置的转义符,在转义序列中使用 |
当 SLIP 驱动程序从互操作层接收 IP 数据报时,它简单地逐字节复制(除了一个小的例外,见下文)并附加一个值为 0xC0(十六进制)的额外字节。这个额外的字节标记 IP 数据报的结束,因此称为 *END* 字符。
为了避免随机线路噪声被解释为数据报的开头,习惯上在 IP 数据报之前添加 *END* 字符,如果数据报不是连续且以全速发送到线路上的,并且传输恢复。这样,可能的随机噪声本身就被封装成一个数据报,而更高层(特别是 IP 层)将丢弃这些“数据报”,因为它们将被识别为非法的(错误的校验和、错误的大小、低于最小大小)。
连续发送时的帧
+-----------------+-----------------+-----------------+ | IP datagram |END| IP datagram |END| IP datagram |END| ... +-----------------+-----------------+-----------------+
延迟发送数据包时的帧,在数据包之前添加额外的 END 字符以排除线路噪声
+-----------------+ +----+-----------------+ +----+-----------------+ | IP datagram |END| line noise |END | IP datagram |END| line noise |END | IP datagram |END| ... +-----------------+ +----+-----------------+ +----+-----------------+
上图中用红色标记的 END 字符是在它们后面的 IP 数据报之前添加的 END 字符。但它们实际上充当前面线路噪声的结束标记,将潜在的随机线路噪声与真实数据分开。
用 0xC0 *END* 字符进行帧定界会产生一个问题。如果该字符本身出现在 IP 数据报中,SLIP 会错误地将它解释为数据报的结束。这个问题通过引入另一个特殊字符 *ESC* 字符(值为 0xDB(十六进制))来解决。它用于构建两个转义序列
- 0xDB 0xDC
- 替换 IP 数据报内的 0xC0 值
这确保了传输数据报中永远不会出现 *END* 字符 - 0xDB 0xDD
- 替换 IP 数据报内的 0xDB 值
这是“转义转义”字符。
SLIP 将这些转义序列插入它从互操作层接收的 IP 数据报中进行传输,并在转发接收到的数据报到互操作层时用原始值替换转义序列。
这就是 SLIP 所做的全部。没有错误检测、压缩或设备(调制解调器)控制。也没有对主机配置、安全性、会话管理和其他控制功能的支持。因此,SLIP 本身在容易出错的拨号连接上并不令人满意,尽管它在 MNP4(或更高版本)错误纠正调制解调器链路上可靠地运行。
本节是残缺的。 你可以通过 扩展它 来帮助 Wikibooks。 |
PPP(点对点协议)提供了一种标准方法,用于在点对点链路上传输数据报,包括标准串行线。PPP 的规范定义了以下三个主要组成部分
- 一种在 PPP 帧中封装数据报的方法。它支持 IP 数据报以及其他网络协议的数据报。
- 链路控制协议 (LCP)。该协议定义了建立、配置和测试数据链路连接的过程。
- 一个网络控制协议 (NCP) 家族,用于建立和配置不同的网络层协议。
PPP 是一个相当复杂的协议,由强制性和可选部分以及扩展组成。下面列出了一个可能不完整的 PPP 相关 RFC 标准列表
- RFC 1661 - 点对点协议 (PPP)
- RFC 1332 - PPP 互联网协议控制协议 (IPCP)
- RFC 1334 - PPP 认证协议
- RFC 1377 - PPP OSI 网络层控制协议 (OSINLCP)
- RFC 1378 - PPP AppleTalk 控制协议 (ATCP)
- RFC 1552 - PPP 互操作分组交换控制协议 (IPXCP)
- RFC 1570 - PPP LCP 扩展
- RFC 1618 - PPP over ISDN
- RFC 1662 - PPP 在类似 HDLC 的帧定界中
- RFC 1962 - PPP 压缩控制协议 (CCP)
- RFC 1968 - PPP 加密控制协议 (ECP)
- RFC 1973 - PPP 在帧中继中
- RFC 1989 - PPP 链路质量监控
- RFC 1990 - PPP 多链路协议 (ML)
- RFC 1994 - PPP 质询握手身份验证协议 (CHAP)
- RFC 2043 - PPP SNA 控制协议 (SNACP)
- RFC 2097 - PPP NetBIOS 帧控制协议 (NBFCP)
- RFC 2125 - PPP 带宽分配协议 (BAP) / PPP 带宽分配控制协议 (BACP)
- RFC 2290 - PPP IPCP 的移动 IPv4 配置选项
- RFC 2364 - PPP over AAL5
- RFC 2472 - PPP 上的 IPv6 版本
- RFC 2516 - 通过以太网传输 PPP 的方法 (PPPoE)
- RFC 2615 - PPP over SONET / SDH
简而言之,实现 PPP 并非易事。这是一项严肃的任务,需要扎实的编程、协议和电信知识,即使只考虑与串行线路通信相关的部分。希望实现 PPP 的程序员应该提前预留数周时间来学习相关标准。定义需要实现哪些可选 PPP 部分的明确需求也是一个好主意。还应该考虑获得兼容性测试套件以验证自身实现的标准符合性。对现有协议消费者实现进行简单的试错通常不切实际。这只能在一定程度上“保证”PPP 实现与特定配置下的特定其他实现兼容。它不能保证该实现与各种现有的 PPP 实现兼容。
如果购买特定平台的 PPP 实现是一个可行的选择,而不是进行自己的实现,那么应该认真考虑这个选择。
本节是残缺的。 你可以通过 扩展它 来帮助 Wikibooks。 |
HDLC(高级数据链路控制)是另一个第二层协议,可用于在串行(和其他)连接上承载 IP 流量。HDLC 早于 PPP 并且是一个通用的第二层协议。它可以在工业应用中找到,并且在 IP 路由器 之间的串行点对点链路中也很流行。它在最终用户应用程序(如拨号连接到 ISP)中并不常见。关于 HDLC 的维基百科文章 提供了关于 HDLC 的良好概述,并提供了对相关标准的引用。
HDLC 主要关注帧定界,并提供了一些额外的控制消息(*过程*)。它在串行线上相对容易实现。
串行编程: 介绍和 OSI 网络模型 -- RS-232 布线和连接 -- 典型的 RS232 硬件配置 -- 8250 UART -- DOS -- MAX232 驱动器/接收器系列 -- Windows 中的 TAPI 通信 -- Linux 和 Unix -- Java -- Hayes 兼容调制解调器和 AT 命令 -- 通用串行总线 (USB) -- 形成数据包 -- 错误校正方法 -- 双向通信 -- 数据包恢复方法 -- 串行数据网络 -- 实际应用开发 -- 串行连接上的 IP