如何根据具体需要选择正确的套接字族、类型和协议来创建套接字



我正在用python做一些网络编程的东西。我知道套接字可以像下面这样创建…

TCP套接字

socket.socket(
family = socket.AF_INET,
type   = socket.SOCK_STREAM,
proto  = socket.IPPROTO_IP,
fileno = None)
socket.socket(
family = socket.AF_INET,
type   = socket.SOCK_STREAM,
proto  = socket.IPPROTO_TCP,
fileno = None)

UDP套接字

socket.socket(
family = socket.AF_INET,
type   = socket.SOCK_DGRAM,
proto  = socket.IPPROTO_IP,
fileno = None)
socket.socket(
family = socket.AF_INET,
type   = socket.SOCK_DGRAM,
proto  = socket.IPPROTO_TCP,
fileno = None)

为原始套接字捕获所有数据包…

socket.socket(
family = socket.AF_PACKET,
type   = socket.SOCK_RAW,
proto  = socket.htons(0x0003),
fileno = None
)

我一直在做TCP, UDP和原始套接字。除了TCP和UDP,还有许多其他协议,Python套接字库也支持这些其他协议。但当我尝试用其他协议做一些工作时,事情并不总是正确的。有时,在创建套接字时,一切看起来都是正确的,但会产生错误。在创建套接字时,我对家庭,类型和协议的组合将正确地组合在一起有很多困惑。我有意识地没有在这里给出任何特定的代码示例来更好地解释我的问题,相反,我正在寻找正确创建套接字所需的网络和协议相关逻辑和知识。

请分享你对这个话题的看法和评论。

文档说:

Python接口是Unix系统调用和套接字库接口的直接音译…

所以你应该阅读系统底层套接字库的文档。

例如,我的本地Linuxsocket(3P)手册说:

如果protocol参数不为零,它应该指定一个地址族支持的协议。[…系统支持的协议是由实现定义的。

你还没有告诉我们你的底层系统是什么,但这是你应该开始寻找的地方。

不能混用和匹配参数。也许当他们在1983年设计套接字API时,他们认为你可以,但事实并非如此。

您必须查看您想要创建的套接字的具体类型,然后使用它所说的参数。

我从来没有听说过DGRAM ICMP套接字,ICMP的文档也没有说你可以创建一个。对于ICMP,您需要使用SOCK_RAW,它给您一个原始的IP套接字。

DGRAM ICMP似乎是Linux中的一个选项,但它需要特殊的设置才能使其工作,并且它没有很好的文档:ICMP套接字(Linux),显然,它不适合您。它是一种不同类型的套接字,它的行为与原始套接字不同。

最新更新