我偶然发现了一件奇怪的事情,我看到的应用程序是默认使用SOCK_STREAM函数。为甚麽呢?这个SOCK_STREAM只是创建了多个流吗?或者它是可用于创建TCP流的标准SOCK_STREAM函数?
我认为海啸是基于UDP的,但仍然具有TCP的一些特性,例如TCP公平性、友好性等。
有没有人能解释一下这个问题?我对此感到非常困惑。
发布于 2012-05-30 12:36:01
TCP几乎总是使用SOCK_STREAM,UDP使用SOCK_DGRAM。
TCP (SOCK_STREAM)是一个基于连接的协议。建立连接,并且双方进行会话,直到连接被其中一方或网络错误终止。
UDP (SOCK_DGRAM)是基于数据报的协议。您发送一个数据报并得到一个回复,然后连接终止。
TCP
根据您希望与其他计算机进行交互的方式选择合适的协议。
发布于 2020-02-27 11:14:18
背后的一个想法是它可以使用不同的 -而不仅仅是互联网协议(IP)。但是你有一个可以处理所有类型的“地址族”的API,例如:
AF_INET
AF_IPX
AF_APPLETALK
AF_NETBIOS
AF_INET
AF_IPX
AF_APPLETALK
AF_NETBIOS
AF_INET6
关于如何在套接字上处理数据,每个协议族通常都有几个类似的概念:
数据报序列化的、可靠的、双向的、基于连接的、字节流:SOCK_STREAM ( IP人员会称其为
SOCK_STREAM( IP人员将其称为SOCK_DGRAM )不同的地址族对这些基本概念有不同的术语:
╔═══════════╦══════════════════════════╗
║ ║ 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
。
类似地,如果我在红外线(IrDA,AF_IRDA)上创建套接字:
我不知道IrDA中哪种协议是可靠的、顺序的,我只知道我想要可靠的、顺序的和connection-based的IrDA
所以你会说:
socket(AF_IRDA, SOCK_STREAM, 0);Sockets会帮我解决的。
奖金
最初只有两个协议选项:
SOCK_DGRAM)SOCK_STREAM)后来添加了其他协议选择:
在基于数据报(SOCK_SEQPACKET)的新的programs)
SOCK_RDM -“可靠数据报多播”-已过时╔═══════════╦══════════════════════════════════════════════════════╗
║ ║ 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协议是多余的:
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // passing IPPROTO_TCP is redundant
socket(AF_INET, SOCK_STREAM, 0); // better你已经说过你想要一台SOCK_STREAM了。你不需要强迫TCP在它上面。同样,调用以下代码也是多余的:
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //passing IPPROTO_UDP is redundant
socket(AF_INET, SOCK_DGRAM, 0); // betterTCP tl;dr:这是一种与协议无关的请求TCP或UDP的方式。但是由于这个星球上没有人再使用AppleTalk,IPX/SPX,IrDA,蓝牙,NetBIOS,它基本上是残留的。
发布于 2011-04-28 19:48:25
更新: UDP我的答案似乎不再相关,但最初的问题提到了,这是一个建立在UDP之上的面向连接的协议。更多信息请点击此处:http://en.wikipedia.org/wiki/UDP-based_Data_Transfer_Protocol
UDT似乎提供了模仿经典BSD套接字API的API,因此它可以作为面向流和面向数据报的应用程序的替代。检查例如sendmsg和recvmsg -如果在用SOCK_STREAM创建的套接字上使用,两者都会抛出异常,所有面向流的API也都会对用SOCK_DGRAM创建的套接字抛出异常。
在SOCK_DGRAM情况下,它执行一些额外的处理,但是,在这种情况下,它并不是简单地透明地包装UDT就我在快速复习之后所理解的代码而言(我不熟悉UDT内部结构或协议规范)。阅读technical papers可能会有很大帮助。
该库始终将其底层的“真实”套接字创建为数据报套接字(请检查channel.cpp,CChannel::open)。
https://stackoverflow.com/questions/5815675
复制相似问题