是否可以通过 TCP 发送数据报?

发布于 2024-08-28 10:26:56 字数 83 浏览 6 评论 0原文

理论上,没有什么可以阻止将 TCP 套接字与 SOCK_DGRAM 一起使用。您将获得可靠的数据报传输。使用 Berkeley 套接字可以实现这一点吗?

In theory nothing prevents using TCP socket with SOCK_DGRAM. What you'll get is reliable datagram transport. Is this possible using Berkeley sockets?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

锦欢 2024-09-04 10:26:56

您想要查看的是 SCTP 协议。它提供了通过可靠的 TCP 样式连接发送数据报的能力:

与 TCP 相比,SCTP 可能是
其特点是面向记录,
这意味着它传输数据的方式是
消息,以类似的方式
用户数据报协议 (UDP),以便
一次发送的一组字节(消息)
传输操作(记录)是
完全按照该组的方式阅读
接收器应用程序。 TCP 是
面向流,传输流
字节数,它正确地重新排序
如果发生无序交货。它
然而,不尊重信息
边界,即结构
数据按其原始数据
发送方的传输单元。

查看 SCTP 一对一风格的连接,这可能就是您正在寻找的。

大多数 Unix / Linux 操作系统都有实现,Windows 也有第三方实现。有关详细信息,请参阅我链接的 Wiki 文章的末尾。

What you want to take a look at is the SCTP Protocol. It provides the ability to send Datagrams over a reliable TCP style connection:

In contrast to TCP, SCTP may be
characterized as record-oriented,
meaning it transports data in terms of
messages, in a similar fashion to the
User Datagram Protocol (UDP), so that
a group of bytes (message) sent in one
transmission operation (record) is
read exactly as that group at the
receiver application. TCP is
stream-oriented, transporting streams
of bytes, which it correctly reorders
in case of out-of-order delivery. It
does not, however, honor message
boundaries, i.e., the structure of
data in terms of their original
transmission units at the sender.

Take a look at SCTP one to one style connections which are probably what you're looking for.

There are implementations for most Unix / Linux OS and there is a third party implementation for Windows. See the end of the Wiki article I linked for details.

韵柒 2024-09-04 10:26:56

SOCK_DGRAM 作为类型为您提供一个 UDP 套接字。当然,您可以将 UDP 封装在 TCP 中,但是您必须在用户空间中处理 UDP 部分。某些东西是否可靠取决于线路上的协议。如果使用TCP,则可靠; UDP 则不然。

创建 UDP 套接字:

int s;
s = socket(AF_INET, SOCK_DGRAM, 0);

创建 TCP 套接字:

int s;
s = socket(AF_INET, SOCK_STREAM, 0);

有两种常见方法可以通过线路发送离散数据块。您可以使用 UDP 并将离散块作为数据报发送,也可以将其构造为 TCP 数据,然后将它们作为流发送。使用 TCP 通常更简单且不易出错。如果您使用 UDP,则只需超时并继续请求相同的数据,直到获得为止。

SOCK_DGRAM as the type gets you a UDP socket. You can encapsulate UDP in TCP of course, but you'd have to handle the UDP part in userspace. Whether something is reliable depends on the protocol on the wire. If you use TCP, it is reliable; UDP is not.

To create a UDP socket:

int s;
s = socket(AF_INET, SOCK_DGRAM, 0);

To create a TCP socket:

int s;
s = socket(AF_INET, SOCK_STREAM, 0);

There are two common ways to send discrete chunks of data across the wire. You can either use UDP and send a discrete chunk as a datagram, or you can but structs into TCP data, and let them go as a stream. Using TCP is generally simpler and less failure-prone. If you use UDP, just time out and keep requesting the same data until you get it.

笛声青案梦长安 2024-09-04 10:26:56

理论上,没有什么可以阻止使用带有 SOCK_DGRAM 的 TCP 套接字。您将获得可靠的数据报传输。使用 Berkeley 套接字可以实现这一点吗?

不,Berkeley API 提供不可靠的数据报或可靠的流。

如果您想通过 TCP 发送可靠的块,请使用某种将流拆分为块的协议。这很简单。

In theory nothing prevents using TCP socket with SOCK_DGRAM. What you'll get is reliable datagram transport. Is this possible using Berkeley sockets?

No, Berkeley API provides unreliable datagram or reliable stream.

If you want to send reliable chunks over TCP use some protocol that splits stream into chunks. That is very simple to do.

凡尘雨 2024-09-04 10:26:56

并不真地。 TCP和UDP是同一层的协议,它们具有只对它们有意义的功能。以listen()和accept()为例。

您可以在 TCP 数据包内发送 UDP 标头+数据,但根本没有意义。
你为什么要这么做?一种隧道掘进?事实上,手动解析和构建 UDP 数据包非常容易,但我在您的场景中没有看到真正的应用程序。

Not really. TCP and UDP are protocols from the same layer, and they have functions that make sense only to them. Take listen() and accept() for instance.

You could send UDP header+data inside TCP packets, but doesn't make sense at all.
Why would you do that? A specie of tunnelling? In fact, it's very easy to parse and build UDP packets by hand, but I don't see a real application in your scenario.

影子是时光的心 2024-09-04 10:26:56

我还没有看到任何套接字 api 可以为您提供此选项 - 而且它还会破坏 TCP 让您控制数据对齐的一些目的。 TCP只是传输,它的抽象是字节流。

您必须在 TCP 之上构建自己的消息结构,为您提供应用程序层关心的消息概念。

I've not seen any socket api that give you this option - and it would also defeat some of the purpose of TCP to let you control the data alignment. TCP is just the transport, and its abstraction is a byte stream.

You will have to build your own message structure on top of TCP that gives you the concept of messages that the application layer care about.

半岛未凉 2024-09-04 10:26:56

您可以模拟事物,但实际上没有理由这样做。您要么想要可靠的交付,要么想要及时的交付。 TCP 提供第一个,UDP 提供第二个。两者不能混合,因为 TCP 通过反复告知另一端消息直至得到确认来实现可靠性。对于流式传输,您通常需要可靠的数据传递(以便您可以重新组装流),但对于顺序不重要的小消息(即数据报),您不需要所有这些开销(UDP 确实在很大程度上保证了消息在至少不会出现乱码;这是 TCP 和 UDP 通过原始 IP 提供的功能之一)。

当然,在这两个极端之间还有一些其他有趣的案例。对于实时流数据(例如视频通话),您可以使用 RTP 因为您正在流式传输,但可以比延迟更好地从数据丢失中恢复。对于对于 UDP 来说太大的消息(64kB 是严格的上限,因为 UDP 标头的长度字段只有 16 位),您几乎需要使用 TCP 进行传输,以便您可以重新组装片段(因此SOAP 通过 HTTP 通过 TCP,而不是通过 UDP)。

You can simulate things, but there's really no reason to do so. Either you want reliable delivery or you want timely delivery. TCP gives you the first, UDP gives the second. The two can't mix because TCP implements reliability by repeatedly telling the other end about the messages until they're acknowledged. For streaming, you generally need reliable delivery of data (so you can reassemble the stream), but for small messages where order isn't important (i.e., datagrams) you don't need all that overhead (UDP does largely guarantee that messages at least won't arrive garbled; that's one of the things that both TCP and UDP offer over raw IP).

There are some other interesting cases between these two extremes, of course. For real-time streaming data (e.g., video calling), you use RTP because you're streaming but can recover from data loss better than delay. For messages that are too large for UDP (64kB is the strict upper-bound, since the UDP header only has 16 bits for its length field) you pretty-much need to use TCP for transport anyway so that you can reassemble the fragments (hence SOAP goes over HTTP over TCP, and not via UDP).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文