我对网络编程很陌生,并且一直在努力解决这个问题。在通过互联网浏览了大量资源之后,我得出了以下结论,并对此产生了混淆。
结论1: 当我们谈论创建套接字时:
s = socket(AF_INET, SOCK_RAW, 0);
我们基本上是在尝试创建一个原始套接字。使用以这种方式创建的原始套接字,可以绕过OSI堆栈中的TCP / UDP层。这意味着,当应用程序通过此套接字接收到数据包时,应用程序将具有包含网络层(第3层)标头的数据包,其中包含包含实际数据的第2层标头。因此,无论如何,应用程序都可以自由地处理此数据包,超出第3层。
类似地,当通过此套接字发送数据包时,应用程序可以自由地处理数据包创建,直到第4层,然后将其传递到第3层,从内核处理内容。
结论2:当我们谈论创建套接字时:
s = socket(AF_PACKET, SOCK_RAW, 0);
我们再次尝试创建一个原始套接字。使用以这种方式创建的原始套接字,可以完全绕过OSI的所有层。 用户土地应用程序可以使用纯原始数据包,并且可以随意使用该数据包执行任何操作。通过这样的套接字接收的数据包将使所有标头保持完整,并且应用程序也可以访问所有这些标头。
类似地,当通过这样的套接字发送数据时,用户应用程序是必须处理关于数据包的创建以及实际数据的包装以及每个层的标头之前的应用程序。实际上是放在要传输的物理介质上。
结论3:当我们谈论创建套接字时:
s = socket(AF_PACKET, SOCK_DGRAM, 0);
我们再次尝试创建一个原始套接字。使用以这种方式创建的原始套接字,可以绕过OSI堆栈中的数据链路层(第2层)。这意味着,当用户陆地应用程序接收到这种套接字上的分组时,从分组中移除数据链路层报头。
类似地,在通过此套接字发送数据包时,根据sockaddr_ll目标地址中的信息,将一个合适的数据链路层头添加到数据包中。
以下是我的疑问/疑惑点:
我提到的一些资源试图理解上述内容:
https://docs.freebsd.org/44doc/psd/21.ipc/paper.pdf
https://sock-raw.org/papers/sock_raw
https://www.quora.com/in/Whats-the-difference-between-the-AF_PACKET-and-AF_INET-in-python-socket
http://www.linuxcertif.com/man/7/PF_PACKET/
http://opensourceforu.com/2015/03/a-guide-to-using-raw-sockets/
'SOCK_RAW' option in 'socket' system call
http://stevendanna.github.io/blog/2013/06/23/a-short-sock-raw-adventure/