Rust 中同时使用 UDP 和 TCP 协议 [关闭]

Posted

技术标签:

【中文标题】Rust 中同时使用 UDP 和 TCP 协议 [关闭]【英文标题】:UDP & TCP Protocols at the same time in Rust [closed] 【发布时间】:2022-01-20 15:44:28 【问题描述】:

我正在使用 Rust 开发一个应用程序,其中我需要将两种类型的数据传输到 Internet 上的服务器:

很多“不太重要”的信息,我会使用 UDP 协议。 我会使用 TCP 协议的一些“非常重要”的信息。

是否可以同时使用两种协议?或者是否有任何协议(在 Rust 中可用)允许我发送两种类型的信息而不会产生重大后果?

【问题讨论】:

当然可以,但不是同一个端口。 “这样更正确吗?”这真的取决于,这是一种在(编码良好的)服务器 fps 游戏中大量使用的模式。 “是否有任何协议(在 rust 中可用)允许我发送两种类型的信息而不会产生重大后果?”没有任何意义。 也就是说,用 TCP 编写服务器代码已经够难了,用 UDP 编写服务器代码也很困难,因此需要“协同工作”的代码非常困难 @Stargateur: “当然可以,但不是同一个端口” - UDP和TCP都有自己的端口“空间”,即完全可以使用UDP和TCP的端口号相同。甚至很常见:DNS 使用端口 53,基于 UDP 的 HTTP/3 和基于 TCP 的 HTTP 都使用端口 443。 UDP 与 TCP 并不是关于“不太重要”与“非常重要”的关系。 UDP 是关于可以接受消息丢失、重复或重新排序但按时交付很重要的消息,例如实时音频。 TCP 是不惜一切代价进行可靠的按顺序交付,即使会导致更高的延迟。 我将 Steffen Ullrich 的信息表述为:当 TCP 的机制(特别是它实现按顺序传递的方式,也称为行头阻塞和拥塞控制)不是一种选择。通常,您在 UDP 之上有另一个协议,它以您的数据可接受的方式实现类似的事情。 【参考方案1】:

当然,您总是可以同时使用两者来监听不同的端口。 我相信您的问题与 rust 关系不大,更多的是与网络或通信设计有关。

我还使用这两种协议开发了一个类似的项目。

在我的项目中,我编写了一个 socks5 多路复用器。基本上,用户使用任何 socs5 兼容客户端在 TCP 上使用 socks5 协议连接到我的服务器,然后我通过 UDP 将其分发给我的工作人员,他们再次通过 TCP 连接到远程,因为 HTTP 就是这样工作的。

在我的例子中,我选择 UDP 在主节点和从节点之间进行通信的原因是 UDP 是一个基于帧的协议,这使我能够更轻松地实现我的协议,因为我不需要跟踪消息的开始和结束位置只是当我从一个节点向另一个节点发送一个长度为 n 的帧时,另一方面我会读取 n 个字节。 TCP 的情况并非如此。在 TCP 中,可以保证整体内容的完整性,但不能保证特定的帧大小。例如,您可以在一端写入 50 字节,在另一端接收 20 字节和 30 字节。

所以根据你的需要,你应该选择正确的协议,还要了解每个协议的优劣。

总结

TCP: 有利于整体数据完整性,但如果您有基于帧的协议,则非常糟糕。你需要自己的框架逻辑。

UDP: 如果您正在开发基于帧的协议,那就太棒了,但是有些帧有时可能会消失,但不能保证整体完整性。

【讨论】:

你不需要 tcp 和 udp 监听不同的端口。所有套接字都根据 元组进行匹配,其中 proto 是传输协议。 并且使用 UDP 而不是在流中正确定义消息边界是使用 UDP 的一个特别糟糕的原因。 TCP 的成帧逻辑并不难。例如您可以在每帧之前添加一个 4 字节的 uint32 大小标头,并向接收器添加逻辑以解析它以了解下一帧要读取多少字节,然后重复。

以上是关于Rust 中同时使用 UDP 和 TCP 协议 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

DNS何时使用TCP协议,何时使用UDP协议?

DNS同时占用UDP和TCP端口53——传输数据超过512时候用tcp,DNS服务器可以配置仅支持UDP查询包

TCP和UDP 能够同时监听“同一端口”吗

DNS何时使用TCP协议,何时使用UDP协议

干货:DNS何时使用TCP协议,何时使用UDP协议?

DNS使用的是TCP协议还是UDP协议简析