C++ SOCK_DGRAM 和 SOCK_STREAM 是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5815675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:55:48  来源:igfitidea点击:

What is SOCK_DGRAM and SOCK_STREAM?

c++socketsprotocolstcp

提问by echo9

I just came across this strange thing I got to see application is that by default they use SOCK_STREAMfunction. Why is it so? Is this SOCK_STREAMjust creating multiple streams? Or is it the standard SOCK_STREAMfunction available for creating TCP stream(s)?

我刚刚遇到一个奇怪的事情,我看到应用程序默认情况下它们使用SOCK_STREAM函数。为什么会这样?这SOCK_STREAM只是创建多个流吗?或者它是SOCK_STREAM可用于创建 TCP 流的标准功能吗?

I thought tsunami is based on UDP, but still having some features like that of TCP, e.g. TCP fairness, friendlyness, etc.

我以为海啸是基于UDP的,但仍然有一些像TCP一样的特性,例如TCP公平性、友好性等。

Could somebody please shed some light on this issue? I am totally confused over this.

有人可以对这个问题有所了解吗?我对此完全困惑。

回答by Michael J

TCP almost always uses SOCK_STREAMand UDP uses SOCK_DGRAM.

TCP 几乎总是使用SOCK_STREAMUDP 使用SOCK_DGRAM

TCP (SOCK_STREAM) is a connection-based protocol. The connection is established and the two parties have a conversation until the connection is terminated by one of the parties or by a network error.

TCP ( SOCK_STREAM) 是一种基于连接的协议。连接建立并进行对话,直到连接被其中一方或网络错误终止。

UDP (SOCK_DGRAM) is a datagram-based protocol. You send one datagram and get one reply and then the connection terminates.

UDP ( SOCK_DGRAM) 是一种基于数据报的协议。您发送一个数据报并得到一个回复​​,然后连接终止。

  • If you send multiple packets, TCP promises to deliver them in order. UDP does not, so the receiver needs to check them, if the order matters.

  • If a TCP packet is lost, the sender can tell. Not so for UDP.

  • UDP datagrams are limited in size, from memory I think it is 512 bytes. TCP can send much bigger lumps than that.

  • TCP is a bit more robust and makes more checks. UDP is a shade lighter weight (less computer and network stress).

  • 如果您发送多个数据包,TCP 承诺按顺序传送它们。UDP 没有,所以接收方需要检查它们,如果顺序很重要。

  • 如果 TCP 数据包丢失,发送方可以知道。UDP 并非如此。

  • UDP 数据报的大小有限制,从内存中我认为它是 512 字节。TCP 可以发送比这更大的块。

  • TCP 更健壮一点,并进行更多检查。UDP 的重量更轻(计算机和网络压力较小)。

Choose the protocol appropriate for how you want to interact with the other computer.

选择适合您希望如何与另一台计算机交互的协议。

回答by Code Painters

Update:my answer seems no more relevant, but the original question referred to UDT, which is a connection-oriented protocol built on top of UDP. More info here: http://en.wikipedia.org/wiki/UDP-based_Data_Transfer_Protocol

更新:我的答案似乎不再相关,但最初的问题提到了 UDT,它是一种建立在 UDP 之上的面向连接的协议。更多信息在这里:http: //en.wikipedia.org/wiki/UDP-based_Data_Transfer_Protocol



UDT appears to provide API which mimics classic BSD sockets API, so it can be used as a drop-in replacement, for both stream and datagram oriented applications. Check e.g. sendmsgand recvmsg- both throw an exception if used on a socket created with SOCK_STREAM, and all the stream oriented APIs throw an exception for socket created with SOCK_DGRAMas well.

UDT 似乎提供了模仿经典 BSD 套接字 API 的 API,因此它可以用作面向流和数据报的应用程序的直接替代品。检查 egsendmsgrecvmsg- 如果在使用创建的套接字上使用都会抛出异常SOCK_STREAM,并且所有面向流的 APISOCK_DGRAM也会为使用创建的套接字抛出异常。

In case of SOCK_DGRAMit perform some extra processing however, it doesn't simply wrap the UDP socket transparently in such case - as far as I understand the code after a quick review (I'm not familiar with UDT internals or protocol spec). Reading the technical paperscould help a lot.

SOCK_DGRAM然而,如果它执行一些额外的处理,它不会简单地在这种情况下透明地包装 UDP 套接字 - 就我在快速查看后理解的代码而言(我不熟悉 UDT 内部或协议规范)。阅读技术论文会有很大帮助。

The library always creates its underlying, "real" socket as a datagram one (check channel.cpp, CChannel::open).

该库始终将其底层的“真实”套接字创建为数据报之一(检查 channel.cpp, CChannel::open)。

回答by Ian Boyd

One of the ideas behind socketswas that it could use different protocol families- not just the Internet Protocol (IP). But instead you had one API that could handle all kinds of "address families":

套接字背后的想法之一是它可以使用不同的协议系列——而不仅仅是互联网协议 (IP)。但是相反,您拥有一个可以处理各种“地址系列”的API :

  • Internet Protocol version 4 (IPv4): AF_INET
  • IPX/SPX: AF_IPX
  • AppleTalk: AF_APPLETALK
  • NetBIOS: AF_NETBIOS
  • Internet Protocol version 6 (IPv6): AF_INET6
  • Infrared Data Association (IrDA): AF_IRDA
  • Bluetooth: AF_BTH
  • Internet 协议版本 4 (IPv4): AF_INET
  • IPX/SPX: AF_IPX
  • 苹果谈话: AF_APPLETALK
  • 网络BIOS: AF_NETBIOS
  • 互联网协议版本 6 (IPv6): AF_INET6
  • 红外数据协会 (IrDA): AF_IRDA
  • 蓝牙: AF_BTH

Each protocol familygenerally has a few similar concepts of how data will be handled on a socket:

每个协议族通常都有一些关于如何在套接字上处理数据的类似概念:

  • sequenced, reliable, two-way, connection-based, byte-streams: SOCK_STREAM(what an IPv4 person would call TCP)
  • connectionless, unreliable, datagrams: SOCK_DGRAM(what an IPv4 person would call UDP)
  • 有序的、可靠的、双向的、基于连接的、字节流:SOCK_STREAM(IPv4 人会称之为 TCP)
  • 无连接、不可靠的数据报:SOCK_DGRAM(IPv4 人会称之为 UDP)

Different address families have different terms for these basic concepts:

不同的地址族对这些基本概念有不同的术语:

| Address   |       Socket Type        |
| Family    | SOCK_DGRAM | SOCK_STREAM | 
|-----------|------------|-------------|
| IPX/SPX   | SPX        | IPX         |
| NetBIOS   | NetBIOS    | n/a         |
| IPv4      | UDP        | TCP         |
| AppleTalk | DDP        | ADSP        |
| IPv6      | UDP        | TCP         |
| IrDA      | IrLMP      | IrTTP       |
| Bluetooth | ?          | RFCOMM      |

The point is:

重点是:

  • If you want reliable, two-way, connection-based, sequenced, byte-streams
  • you ask for it using "SOCK_STREAM"
  • and the socketsAPI will worry about figuring out that you want TCP
  • 如果你想要可靠的、双向的、基于连接的、有序的、字节流
  • 您使用“SOCK_STREAM”请求它
  • 并且套接字API 会担心弄清楚您是否需要 TCP

Similarly, if you were creating a socket over Infrared:

同样,如果您正在通过红外线创建套接字:

  • i have no idea what protocol in IrDA is reliable, sequenced, connection-based
  • all i know is that i want something that is relialbe, sequence, connetion-based
  • 我不知道 IrDA 中的哪种协议是可靠的、有序的、基于连接的
  • 我所知道的是,我想要一些可靠的、序列的、基于连接的东西

So you say:

所以你说:

socket(AF_IRDA, SOCK_STREAM, 0);

And Sockets will figure it out for me.

Sockets 会帮我解决这个问题。

Bonus

奖金

Originally there was only the two protocol options:

最初只有两个协议选项:

  • connectionless, unreliable, datagrams (SOCK_DGRAM)
  • connection-based, reliable, sequenced, two-way (SOCK_STREAM)
  • 无连接、不可靠、数据报 ( SOCK_DGRAM)
  • 基于连接的、可靠的、有序的、双向的 ( SOCK_STREAM)

Later other protocol choices were added:

后来添加了其他协议选择:

  • a reliable message datagram (SOCK_RDM)
  • pseudo-stream sequenced packets based on datagrams (SOCK_SEQPACKET)
  • 可靠的消息数据报 ( SOCK_RDM)
  • 基于数据报的伪流排序数据包 ( SOCK_SEQPACKET)

It's not guaranteed that any given address family will support such protocol choices; but some do.

不能保证任何给定的地址族都支持此类协议选择;但有些人会。

tl;dr: It's a protocol-independant way of asking for TCP or UDP. But since nobody on the planet uses AppleTalk, IPX/SPX, IrDA, BlueTooth, NetBIOS anymore, it's mostly vestigal.

tl;dr:这是一种独立于协议的请求 TCP 或 UDP 的方式。但是由于地球上没有人再使用 AppleTalk、IPX/SPX、IrDA、BlueTooth、NetBIOS,它大多是残留的。