我刚刚遇到这个奇怪的事情,我看到应用程序是默认情况下他们使用SOCK_STREAM
函数。为什么会这样?这个SOCK_STREAM
只是创建多个流吗?或者它是可用于创建TCP流的标准SOCK_STREAM
函数?
我认为海啸基于UDP,但仍然具有类似TCP的功能,例如: TCP公平,友好等。
有人可以就这个问题说清楚吗?我完全对此感到困惑。
答案 0 :(得分:43)
TCP几乎总是使用SOCK_STREAM
,UDP使用SOCK_DGRAM
。
TCP(SOCK_STREAM
)是一种基于连接的协议。建立连接,双方进行对话,直到其中一方或网络错误终止连接。
UDP(SOCK_DGRAM
)是一种基于数据报的协议。您发送一个数据报并获得一个回复,然后连接终止。
如果发送多个数据包,TCP承诺按顺序发送它们。 UDP没有,所以接收者需要检查它们,如果订单 事项。
如果TCP数据包丢失,发件人可以告诉。 UDP不是这样。
UDP数据报的大小有限,从内存我认为是512 字节。 TCP可以发送比这更大的块。
TCP更健壮,可以进行更多检查。 UDP是一种阴影 重量更轻(减少计算机和网络压力)。
选择适合您与其他计算机进行交互的协议。
答案 1 :(得分:18)
Berkley Sockets API 背后的想法之一是它可以使用不同的 protocol families -而不仅仅是Internet协议(IP)。但是相反,您拥有一个可以处理各种“地址族” 的API,例如:
AF_INET
AF_IPX
AF_APPLETALK
AF_NETBIOS
AF_INET6
AF_IRDA
AF_BTH
每个协议家族通常都有一些关于如何在套接字上处理数据的类似概念:
SOCK_STREAM
(IP人员将其称为TCP) SOCK_DGRAM
(IP人员将其称为UDP的信息) 不同的地址族对于这些基本概念有不同的术语:
| 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 |
重点是:
类似地,如果我正在通过红外线(IrDA,AF_IRDA
)创建套接字:
所以你说:
socket(AF_IRDA, SOCK_STREAM, 0);
Sockets会帮我解决这个问题。
最初只有两个协议选项:
SOCK_DGRAM
)SOCK_STREAM
)后来增加了其他协议选择:
SOCK_RDM
)SOCK_SEQPACKET
)的伪流排序数据包不能保证任何给定的地址族都支持这样的协议选择;但是有的。
tl; dr:这是请求TCP或UDP的与协议无关的方式。但是,由于地球上没有人再使用AppleTalk,IPX / SPX,IrDA,蓝牙,NetBIOS,因此大多是遗留的。
答案 2 :(得分:7)
更新:我的回答似乎不再相关,但最初的问题涉及UDT,这是一种建立在UDP之上的面向连接的协议。更多信息:http://en.wikipedia.org/wiki/UDP-based_Data_Transfer_Protocol
UDT似乎提供了模仿经典BSD套接字API的API,因此它可以用作流和面向数据报的应用程序的替代品。检查例如sendmsg
和recvmsg
- 如果在使用SOCK_STREAM
创建的套接字上使用,则抛出异常,并且所有面向流的API都会为使用SOCK_DGRAM
创建的套接字抛出异常。
如果SOCK_DGRAM
它执行了一些额外的处理,但它并不是简单地在这种情况下透明地包装UDP套接字 - 只要我在快速审查后理解代码(我不熟悉) UDT内部或协议规范)。阅读technical papers可能会有很大帮助。
库总是将其底层的“真实”套接字创建为数据报套(检查channel.cpp,CChannel::open
)。
答案 3 :(得分:-2)
TCP 使用 SOCK_STREAM,UDP 使用 SOCK_DGRAM。