Linux SOCK_RAW和SOCK_STREAM有什么区别?

5
最近我一直在学习网络编程、c编码和密码学,在思考一些随机问题时,我偶然发现了一个用于数据包嗅探的代码块,并对函数recvfrom()中使用的实际套接字产生了疑问。通过以下 sock 函数完成套接字初始化: rawSock = socket(AF_INET, SOCK_RAW, 0)
我明白SOCK_STREAMSOCK_RAW是代表整数的宏,但问题不在于这些值,而在于结果。
什么情况下我应该使用SOCK_STREAM而非SOCK_RAW,反之亦然?
我了解使用SOCK_STREAM进行基本客户端和服务器通信。我正在使用 C 在 Linux 上工作。

1
相关链接:https://dev59.com/R2Uq5IYBdhLWcg3wHs2Y - alk
1
简单来说,SOCK_STREAM 使用 TCP/IP,也就是 TCP 通过 IP 进行传输。而 SOCK_RAW 则仅使用 IP,无论你使用或实现什么。 - alk
1
相关问题:https://dev59.com/O2Yr5IYBdhLWcg3w4t3m - alk
1
初学者级别的回答:你永远不会使用 SOCK_RAW。专家级别的回答:除非... - Antti Haapala -- Слава Україні
1
除非你想要嗅探网络。 - user6090272
1个回答

3

阅读手册

对于原型

int socket(int domain, int type, int protocol);

这些类型可以是:

   SOCK_STREAM     Provides sequenced, reliable, two-way, connection-
                   based byte streams.  An out-of-band data transmission
                   mechanism may be supported.

或者

   SOCK_RAW        Provides raw network protocol access.

简而言之,SOCK_STREAM 用于连接导向的套接字,操作系统创建和管理L4(TCP)、L3和L2的头部。另一方面,SOCK_RAW 提供了更精细的控制头部和数据包构建的方式,用户必须构造并提供头部,并可以管理内容。
详细解释如下:
使用 SOCK_STREAM 类型的套接字可进行全双工字节流传输。它们不会保留记录边界。在发送或接收任何数据之前,流式套接字必须处于已连接状态。使用 connect(2) 调用创建到另一个套接字的连接。一旦连接成功,可以使用 read(2) 和 write(2) 调用或某个变体的 send(2) 和 recv(2) 调用来传输数据。当会话完成后,可以执行 close(2)。也可以按照 send(2) 中所述进行带外数据传输,并按照 recv(2) 中所述接收带外数据。
SOCK_RAW 套接字允许通过 sendto(2) 调用将数据报发送给指定的通信对方。通常使用 recvfrom(2) 接收数据报,该函数返回下一个数据报及其发送者的地址。

1
这是你在上次引用中遗漏的部分: "SOCK_DGRAM and" ;-) - alk
1
@alk 这就是为什么我把源代码放在第一行的原因。 :) - Sourav Ghosh
7
那么,下一个问题可能是:“SOCK_DGRAMSOCK_RAW之间有什么区别?” - alk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接