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
What is SOCK_DGRAM and SOCK_STREAM?
提问by echo9
I just came across this strange thing I got to see application is that by default they use SOCK_STREAM
function. Why is it so? Is this SOCK_STREAM
just creating multiple streams? Or is it the standard SOCK_STREAM
function 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_STREAM
and UDP uses SOCK_DGRAM
.
TCP 几乎总是使用SOCK_STREAM
UDP 使用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. sendmsg
and 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_DGRAM
as well.
UDT 似乎提供了模仿经典 BSD 套接字 API 的 API,因此它可以用作面向流和数据报的应用程序的直接替代品。检查 egsendmsg
和recvmsg
- 如果在使用创建的套接字上使用都会抛出异常SOCK_STREAM
,并且所有面向流的 APISOCK_DGRAM
也会为使用创建的套接字抛出异常。
In case of SOCK_DGRAM
it 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,它大多是残留的。