TCP可以通过UDP实现吗?

38

我有一个奇怪的想法。据我所知,有些软件使用UDP传输文件,以减少在TCP数据包中发现的开销。

如果我的应用程序需要TCP,并且我的局域网已经设置了软件,可以与另一端数据中心上的软件进行通信。是否可能通过UDP发送实际数据,然后在两端模拟TCP?

有没有人对这样的项目有任何想法或信息?


3
问题为什么会受到负评?-编辑-也许是因为我提到了非自由软件?我不知道有什么非自由软件,但我已经编辑了这个问题。 - user34537
9个回答

28

如果您想知道是否可以将UDP用作数据链路层,那么答案是有一定程度的可行性。有各种协议可以使用UDP传输创建到另一个网络的隧道,例如L2TP和甚至IPsec(带NAT穿越)。您也可以在应用层进行操作。

如果您想知道TCP是否可以在UDP中实现,答案是否定的。首先,TCP数据包UDP数据包具有不兼容的格式。其次,TCP和UDP具有不同的协议号码(在IP头部中可见),这意味着针对UDP端口的TCP流量将无法传递到正确的上层协议。


2
你可能对“模拟”这个词的理解过于字面,或者我没有完全理解OP对“模拟”的使用。无论如何,只要发送方和接收方应用程序编写得足够好,就可以将TCP头部塞入UDP数据字段中,并使用应用程序逻辑来处理TCP语义。这种方式似乎效率低下,但数据就是数据。唯一的要求是发送方和接收方应用程序在格式和处理语义上达成一致。 - Chuck Wolber
@ChuckWolber,是的,这是一个具有挑战性的问题,因为有多种解释方式。但我认为在我的回答中已经解决了这个问题,当我说“各种协议允许您使用UDP传输创建到另一个网络的隧道”时,我已经解决了这个问题。你提到的方法或多或少与此相符。根据OP问题中的措辞,“我的应用程序需要TCP”,我假设发送方和接收方可能无法就新协议达成一致。 - mpontillo

17

TCP和UDP都是基于IP协议的,但TCP使用不同的数据包结构,在第二层中不能使用UDP数据包模仿TCP。

当然,如果您可以控制源和目标,那么可以为TCP数据包创建可靠的UDP隧道。这需要在UDP数据包的正文中添加一些内部信息(数据包编号、ack/nack标志)。

有一个有趣的项目http://udt.sourceforge.net/

它是一种基于UDP协议的广播能力可靠文件传输机制。


9
PseudoTCP是一种在UDP之上实现TCP算法的协议。由于NAT穿越对于TCP来说比UDP更加复杂,因此引入了这个协议。但是,某些P2P应用程序确实需要节点之间可靠的数据传输。
就我所知,目前有两种PseudoTCP变体:Libjingle和Libnice。Libjingle是谷歌的开源库,最初用于gtalk。您可以查看来自libjingle的文件共享示例:https://developers.google.com/talk/libjingle/file_share。最近,Chrome桌面也使用了来自libjingle的PseudoTCP实现以获取可靠的连接。

5

现在在Linux-3.18+上实现的一种方法是使用基于UDP的Foo (FOU),该方法实现了通用UDP封装(GUE)。这里有一个很好的FOU介绍ip-fou的手册。

或者,如果您想要一个基于UDP的开源文件传输系统,可以使用UDTUFTPTsunami-UDP,甚至是Google的QUIC(现已停用,转而使用IETF QUIC)。

更新:QUIC 协议现已被 IETF 标准化,它提供了一种安全可靠和不可靠的 UDP 传输替代 TCP。有许多 QUIC 实现 可用。同时,还有越来越多的协议映射到 QUIC 上,例如 HTTP/3DNS over QUIC 等。

5
是的,您可以在UDP上开发一个模拟TCP的协议。然而,如果您完全模拟TCP,它在技术上将具有更多的开销。因为TCP是实现为数据包,而您模拟的TCP是实现在数据包的主体中。
如果您只需要TCP的一两个功能(如基本排序),那么在UDP中实现它是有用的。
Halo使用2-3个UDP协议来模拟TCP的不同功能,然后使用完整的TCP初始化游戏状态。I Shot You First Networking, GDC publication 例如,在某些情况下,他们会发送3个重复的UDP数据包以克服数据包丢失问题。
如果您控制两端的软件,并且构建自己的协议是具有成本效益的,则UDP可以非常灵活。

3
如果我的应用程序需要TCP,并且我的局域网上有软件设置以与另一侧的数据中心通信,那么能否通过UDP发送实际数据,然后在两端模拟TCP?
不行。UDP套接字与TCP套接字处于不同的命名空间中。您将无法在一端编写UDP并在另一端发送或接收TCP。TCP和UDP是对等协议;两者都存在于IP层以上。您不能使用其中一个来欺骗另一个。

这不完全是我要问的,但它确实回答了我的一个问题。如果我无法欺骗它,那么我就不能直接使用TCP应用程序。我能否通过代理让TCP应用程序通过UDP传输数据,直到它到达代理的另一侧(允许另一端的软件也使用TCP)?+1 - user34537
@acidzombie24 你可能可以这样做,但我不明白它的意义所在。如果你保持套接字发送/接收缓冲区较大,则TCP开销会消失在噪音中。我也不明白为什么这不是你要求的准确内容。你说过你的应用程序必须使用TCP。 - user207421

1

为什么不呢?Filecatalyst似乎已经做到了。我几年前就有这个想法,当我看到有一家公司用这个想法建立起来时,我感到非常惊讶。 - user34537
类似于TCP,FileCatalyst实现将数据分成块(类似于TCP窗口),尽管在FileCatalyst中块的大小没有限制。让我简要总结一下:他们重新实现了TCP,并修改了一些功能。它不是UDP,正如你可能想象的那样。 - user978122
你如何在TCP上重新实现TCP?无论如何,“FileCatalyst使用的基于UDP的协议是专有的”。来源:http://www.filecatalyst.com/company/faq/#5 - user34537
是的,但他们在描述中提供了足够的信息,如果有人想要创建类似的东西,他们可以这样做。 - user978122
没错。但是你的回答很清楚,可以进行隧道传输。很好。我也是这么想的,但不确定。(在我写第一条评论之前+1) - user34537

1
TCP的问题在于其算法,而不是其头部。
当然,您可以在UDP之上实现TCP算法。这实际上相当于在UDP数据报内部隧道化TCP数据报。但是,所有这些都只是在每个数据包中添加了几个字节的开销,并要求另一个端点解包数据包。
UDP本身只是IP协议的薄层:它是一种方便的方式,可以访问IP分组交换网络,而无需深入内核或从路由器接收特殊处理。在UDP之上实现可靠传输的主要原因是为了摆脱TCP算法,转而采用更高效的方法。FileCatalyst被提及为一家这样做的公司,而我的公司Data Expedition, Inc.也是如此。
因此,您可以在UDP之上实现TCP算法,但您不会想这样做。

两天前,我弄清楚了为什么互联网使用TCP而不是UDP。但是你为什么说我不想要呢?(一到三句话的原因就可以了) - user34537
1
你不会想要在UDP之上实现TCP,因为这样做没有优势。它仍将使用相同的TCP算法,只是负载空间更少,并且需要在两端都使用代理。使用UDP进行可靠传输的唯一原因是构建自己的(非TCP)算法。这就是我的公司所做的。 - Seth Noble
哦,我忘了提到一个疑似的原因不这样做。因为如果我在UDP上隧道传输TCP,我可能仍需要等待ACK,所以不会有速度上的好处。 - user34537
优点是您的数据包不再受TCP拥塞控制的限制。 - Skyler

0

你可以模拟UDP连接,并且也可以增加可靠性检查、排序、重传等功能。但即便如此,它仍然不是TCP,只是表现得像TCP而已。

当然,一端可以是一种“集线器”或“代理”,进行适配处理。这样,你就不再有一个2端的解决方案,实际上是一个4端的解决方案——一对使用“真实”TCP,另一对使用“自己编织”的“TCP”,并通过一个精心制作的程序将它们组合在一起。


1
...当你让它以那种方式运行时,它已经是TCP了,具有相同的开销,或者更多,因为你受限于在用户模式下所能做的事情,而不是在操作系统内核中。 - user207421
但是不兼容 - 两端都必须这样操作。 - glglgl
这是不可行的,因为TCP和UDP在协议层堆栈上一起位于IP之上,并且彼此互斥。 - glglgl
也许在两端使用某种代理解决方案可以实现吗? - user34537
当然可以 - 使用此解决方案,您可以使用“真实”的TCP来创建应用程序。 - glglgl
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接