首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是SOCK_DGRAM和SOCK_STREAM?

什么是SOCK_DGRAM和SOCK_STREAM?
EN

Stack Overflow用户
提问于 2011-04-28 16:19:14
回答 4查看 105K关注 0票数 62

我偶然发现了一件奇怪的事情,我看到的应用程序是默认使用SOCK_STREAM函数。为甚麽呢?这个SOCK_STREAM只是创建了多个流吗?或者它是可用于创建TCP流的标准SOCK_STREAM函数?

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

有没有人能解释一下这个问题?我对此感到非常困惑。

EN

回答 4

Stack Overflow用户

发布于 2012-05-30 12:36:01

TCP几乎总是使用SOCK_STREAM,UDP使用SOCK_DGRAM

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

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

TCP

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

  • 如果TCP数据包丢失,发送者可以判断。对于UDP并非如此。

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

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

根据您希望与其他计算机进行交互的方式选择合适的协议。

票数 89
EN

Stack Overflow用户

发布于 2020-02-27 11:14:18

背后的一个想法是它可以使用不同的 -而不仅仅是互联网协议(IP)。但是你有一个可以处理所有类型的“地址族”的API,例如:

AF_INET

  • IPX/SPX:AF_IPX

  • AppleTalk:AF_APPLETALK

  • NetBIOS:AF_NETBIOS

  • Internet协议互联网协议版本4 (IPv4):AF_INET

  • IPX/SPX:AF_IPX

  • AppleTalk:AF_APPLETALK

  • NetBIOS:AF_NETBIOS

  • Internet

  • 版本6 (IPv6):AF_INET6

  • Infrared数据关联(IPv4):

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

数据报序列化的、可靠的、双向的、基于连接的、字节流:SOCK_STREAM ( IP人员会称其为

  • ,数据报:SOCK_STREAM( IP人员将其称为SOCK_DGRAM )

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

代码语言:javascript
复制
╔═══════════╦══════════════════════════╗
║           ║       Socket Type        ║
║ Address   ╟────────────┬─────────────╢
║ 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      ║
╚═══════════╩════════════╧═════════════╝

重点是:

TCP套接字如果您想要可靠的、双向的、基于连接的、顺序的byte-streams

  • you使用"SOCK_STREAM"

  • and请求它,
  • 将担心您是否需要TCP

类似地,如果我在红外线(IrDA,AF_IRDA)上创建套接字:

我不知道IrDA中哪种协议是可靠的、顺序的,我只知道我想要可靠的、顺序的和connection-based的IrDA

所以你会说:

代码语言:javascript
复制
socket(AF_IRDA, SOCK_STREAM, 0);

Sockets会帮我解决的。

奖金

最初只有两个协议选项:

  • connectionless,不可靠,数据报(SOCK_DGRAM)
  • connection-based,可靠,有序,双向(SOCK_STREAM)

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

在基于数据报(SOCK_SEQPACKET)的新的programs)

  • pseudo-stream排序包中不使用
  • 可靠消息数据报(SOCK_RDM -“可靠数据报多播”-已过时

代码语言:javascript
复制
╔═══════════╦══════════════════════════════════════════════════════╗
║           ║                      Socket Type                     ║
║ Address   ╟────────────┬─────────────┬──────────┬────────────────╢
║ Family    ║ SOCK_DGRAM │ SOCK_STREAM │ SOCK_RDM │ SOCK_SEQPACKET ║ 
╠═══════════╬════════════╪═════════════╪══════════╪════════════════╣
║ IPX/SPX   ║ SPX        │ IPX         │ ?        │ ?              ║
║ NetBIOS   ║ NetBIOS    │ n/a         │ ?        │ ?              ║
║ IPv4      ║ UDP        │ TCP         │ ?        │ ?              ║
║ AppleTalk ║ DDP        │ ADSP        │ ?        │ ?              ║
║ IPv6      ║ UDP        │ TCP         │ ?        │ ?              ║
║ IrDA      ║ IrLMP      │ IrTTP       │ ?        │ ?              ║
║ Bluetooth ║ ?          │ RFCOMM      │ ?        │ ?              ║
╚═══════════╩════════════╧═════════════╧══════════╧════════════════╝

不能保证任何给定的地址族都支持这样的协议选择;但有些地址族确实支持。

红利闲聊

希望您现在明白了为什么在创建套接字的调用中传递IPPROTO_TCP协议是多余的:

代码语言:javascript
复制
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // passing IPPROTO_TCP is redundant
socket(AF_INET, SOCK_STREAM, 0);           // better

你已经说过你想要一台SOCK_STREAM了。你不需要强迫TCP在它上面。同样,调用以下代码也是多余的:

代码语言:javascript
复制
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //passing IPPROTO_UDP is redundant
socket(AF_INET, SOCK_DGRAM, 0);           // better

TCP tl;dr:这是一种与协议无关的请求TCP或UDP的方式。但是由于这个星球上没有人再使用AppleTalk,IPX/SPX,IrDA,蓝牙,NetBIOS,它基本上是残留的。

票数 39
EN

Stack Overflow用户

发布于 2011-04-28 19:48:25

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

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

SOCK_DGRAM情况下,它执行一些额外的处理,但是,在这种情况下,它并不是简单地透明地包装UDT就我在快速复习之后所理解的代码而言(我不熟悉UDT内部结构或协议规范)。阅读technical papers可能会有很大帮助。

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

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5815675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档