3

如何开发 Linux 内核模块以使 UDP 可靠?这是我的大学作业,我不知道如何进行。如何通过加载新的内核模块来更改 linux 内核中的默认 UDP 行为?以及如何编写这样的内核模块?

4

15 回答 15

15

可靠的 UDP 与仅使用 TCP 不同。有许多不同之处,但最主要的是保证您始终会收到完整的 UDP 消息或根本不会收到它。然而,接收部分 TCP 消息不仅可能而且很常见。

由于这只是一个家庭作业,我建议只实现一个发送消息,等待一个 ACK​​,发送下一个超时消息例程。如果超时开始,则在声明失败之前重新发送消息若干次。是的,这将比必要的慢。有很多技术可以提高吞吐量,但对于您的任务,您可能不需要使用它们。

于 2009-04-13T17:33:28.263 回答
10

实际上可靠的 UDP,它被称为RUDP,它是为计划 9 发明的。但是,这真的没有意义,只是使用 TCP。

编辑:另外,UDT可能有用。它基于UDP,但可靠。

于 2009-04-13T17:21:34.317 回答
6

那些一直告诉可怜的人“只使用 TCP”的人忽略了为什么在 TCP 上使用可靠的 UDP 实现是有充分理由的——这不是数据报语义(它很容易在 TCP 之上分层)

一个主要的合法驱动因素是许多节点之间的无连接通信,否则可能需要承载过多的连接多重性

这通常用于广播数据馈送、集群内系统软件通信等。

于 2010-03-31T17:49:56.773 回答
3

我认为询问如何使 UDP 可靠可能会以错误的方式解决这个问题。根据定义,UDP 或多或少是不可靠的 - ipso facto。您将无法使协议的操作系统端实现更加“可靠”。

许多使用 UDP 的应用程序都使用它,因为它们需要它的低开销、低延迟特性,而不是它们需要 TCP 的精确可靠性。但是几乎所有这些应用程序仍然需要一些机制来验证端到端接收某些类型的消息,甚至可能需要重新组装和/或初始握手。例如,考虑 VoIP 电话中的 SIP;TCP 潜在的三向握手和非常渐进的拥塞控制对于体面的呼叫建立时间或 QoS 来说是不可接受的,但肯定需要某种方式来确认消息(这就是临时响应的用途,在 SIP 术语中)。或者网络游戏使用的各种协议——基本思想相同。

很可能分配的真正意图——即使没有明确说明——与其说是使UDP可靠,不如说是创建一个使用UDP在其自己的通信方案中具有一些原始可靠性抽象层的简单程序,封装在UDP中。

于 2009-04-14T06:58:54.710 回答
3

我经常使用 UDP,而我最终看到的主要“可靠性”问题是丢失数据包(尤其是在分段的 IP 数据包中)。您可以通过防止碎片(添加一个将数据报分成 IP 大小的块)以及让 recipeint 检测并请求重新发送丢失的“块”来完成 90% 的工作。

但是,这种东西确实是 TCP 的发明目的。UDP 最适合用于时间敏感的数据,无论如何重新发送都会过时。

有一个网络拓扑解决方案。只需安排好事情,以免发生任何冲突(LAN 上丢失数据包的第一来源)。以下是我为使 UDP 可靠所做的工作:

  • 一个客户端和服务器放在专用的以太网链路上(可能在它们之间有一个交换机,但在它们的专用 LAN 上没有其他系统)。
  • 在 UDP LAN 上保持严格的客户端-服务器通信协议。除非响应客户端,否则服务器永远不允许交谈。
  • 关闭该 UDP 链接(Netbios 等)上的所有外部网络垃圾。
  • 使两端的 ARP 表项静态(这样 ARP 就不会每 10 分钟干扰一次)。

(注意:最后一个特别重要。在许多系统上,导致 ARP 请求的 IP 数据包只是被丢弃,而不是在解析 ARP 后发送)。

于 2009-04-13T17:53:16.173 回答
3

可靠传输数据的技术统称为“ARQ”,代表自动重复请求。

此处解释的主题过于冗长,但维基百科页面是一个很好的起点,但仅此而已。我建议你拿起一本关于计算机网络的教科书(例如 Tanenbaum 或 Kurose/Ross)然后从那里开始。如果您认为它足以完成您的任务,实施基本的停止等待 ARQ 并忘记更高级的 ARQ 方案,那么构建它们还有很多工作要做。

我没有开发 Linux 内核模块的经验,但是如果您选择更高级的 ARQ 方案之一,如果 ARQ 机制的实现结果证明比将其打包为内核模块需要更多的工作,我不会感到惊讶。

祝你的任务好运。

于 2009-04-13T18:44:43.927 回答
2

就像 TCP 一样,在 UDP 之上覆盖 TCP。“可靠的 UDP”是矛盾的。它不是这样设计的。

于 2009-04-13T17:18:03.763 回答
2

如果您绝对需要一个基于消息的传输层协议,您可以在其中关闭一些 TCP 可靠性功能,例如线头阻塞,请查看SCTP。API 甚至有一个“ UDP 模式”来屏蔽底层连接。

它仍在进行中,所以你不能指望用户拥有它——但如果你只需要它用于你维护的计算机,它应该没问题。它在各种风格的 unix中实现,尽管大部分开发工作都发生在 FreeBSD 中。YMMV。

于 2009-04-13T17:32:55.550 回答
1

如果您想了解有关如何修改 Linux 内核的更多信息,我的第一反应是谷歌“linux 内核”,甚至可能在其中添加“套接字”。Linux Kernel网站看起来可能有一些其他的线索供您参考。

我的建议是

1) 看看 UDP 在 Linux 中是如何实现的
2) 看看 RUDP 是如何实现的(正如有人已经提到的那样)
3) ...(你在这里创造了奇迹)
4) 利润!错误...完成了作业!

于 2009-04-13T18:13:28.637 回答
1

老实说,我想知道这是否是一个技巧问题。需要两方进行通信,除非您已经建立了传达此愿望的协议,否则您绝对无法确保发送者知道(或关心)您希望它重新发送数据包。如果 UDP 本身可以做到这一点,我强烈怀疑内核已经支持它。

你剩下的就是识别和实现一个实现新协议的模块。这没有什么问题,其他人已经给了你建议,我相信你可以使用UDP实现来处理实际的数据包传输。但请记住,它是一种新协议的实现,而不仅仅是稍微扭曲 UDP 以在其中获得新功能。

于 2009-04-14T14:12:31.297 回答
1

我不确定是否有一种简单的方法可以通过新模块修改现有 UDP 代码的行为。

更简单的是获取 UDP 代码(net/ipv4/udp.c)并使用新的 IP 协议号创建一个新模块,并修改此代码以实现您可靠的 UDP 协议。您将需要重命名所有外部符号,以便名称不会与现有符号冲突,找出它在哪里注册协议号 (17) 并更改它,然后更新 Makefile 以构建您的新模块并可能在其中添加一个条目配置文件。

查看 /etc/protocols 以查看已经分配了哪些协议 ID。

编辑:看起来 udp.c 不能作为模块构建。您将需要查看一些其他协议(例如 ipip.c 或 ip_gre.c)以了解如何将您的代码变成模块。

于 2009-04-14T06:51:12.840 回答
0

如果你想要一个可靠的 UDP,你最好的选择是使用 SCTP(流控制传输协议)。它现在是一种完善的协议,可以在任何地方使用。

于 2012-11-06T09:19:33.023 回答
0

您需要考虑可靠的含义。此外,您需要决定是否需要按顺序排列数据包,或者是否可以按顺序排列。如果乱序没问题,您需要提出一个 ACK​​、重新传输和超时方案。您还需要决定是否要处理数据包碎片。如果你能摆脱它,你可能想要限制数据包的大小以防止碎片。

于 2009-04-13T17:19:41.793 回答
0

您可能会陷入“可靠”的概念。您对技术术语的确切含义有明确的概念吗?(或者,更相关的是,我想,你的导师是什么意思。)

当您对协议必须具备哪些特征才能称其为可靠有准确的概念时,这可能会为您的工作提供指导。将其作为最低要求进行构建,而不是迷失在功能更全面的真实环境中-world 实施,也可能使完成你的作业更可行。

于 2009-04-13T18:50:21.527 回答
-2

如果出于某种原因您必须使用 UDP(说真的,只使用 TCP),一些快速简单的可靠性功能将是存在心跳、确认和异或校验和。

于 2009-04-13T17:23:02.877 回答