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

时间:2010-04-09 13:14:54

标签: tcp sockets datagram

理论上没有什么能阻止在SOCK_DGRAM中使用TCP套接字。您将获得可靠的数据报传输。这可能是使用伯克利插座吗?

6 个答案:

答案 0 :(得分:4)

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

  

与TCP相比,SCTP可能是   以记录为导向,   意味着它以数据的形式传输数据   消息,以类似的方式   用户数据报协议(UDP),这样   一组字节(消息)发送到一个   传输操作(记录)是   读完就是那个组   接收器应用。 TCP是   以溪流为导向,运输溪流   字节,它正确重新排序   在无序交付的情况下。它   但是,并不尊重信息   边界,即结构   根据原始数据   发送方的传输单位。

看看SCTP一对一的样式连接,这可能就是你想要的。

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

答案 1 :(得分:3)

SOCK_DGRAM作为类型获取UDP套接字。您当然可以在TCP中封装UDP,但是您必须在用户空间中处理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,只需要超时并继续请求相同的数据,直到你得到它。

答案 2 :(得分:1)

  

理论上没有什么能阻止在SOCK_DGRAM中使用TCP套接字。您将获得可靠的数据报传输。这可能是使用伯克利插座吗?

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

如果要通过TCP发送可靠的块,请使用一些将流拆分为块的协议。这很简单。

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

我没有看到任何套接字api给你这个选项 - 它也会破坏TCP的一些目的,让你控制数据对齐。 TCP只是传输,它的抽象是一个字节流。

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

答案 5 :(得分:-1)

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

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