socket
— 低级网络接口¶
源代码: Lib/socket.py
此模块提供对 BSD socket 接口的访问。它适用于所有现代 Unix 系统、Windows、MacOS 以及其他平台。
注意
某些行为可能与平台相关,因为调用的是操作系统套接字 API。
可用性:不适用于 Emscripten,不适用于 WASI。
此模块在 WebAssembly 平台 wasm32-emscripten
和 wasm32-wasi
上不可用或无法工作。有关更多信息,请参阅 WebAssembly 平台。
Python 接口是将 Unix 系统调用和套接字库接口直接转换为 Python 面向对象风格的结果:socket()
函数返回一个套接字对象,其方法实现了各种套接字系统调用。参数类型比 C 接口中的级别更高:与 Python 文件上的 read()
和 write()
操作一样,接收操作上的缓冲区分配是自动的,发送操作上的缓冲区长度是隐式的。
另请参阅
- 模块
socketserver
简化网络服务器编写的类。
- 模块
ssl
套接字对象的 TLS/SSL 包装器。
套接字家族¶
根据系统和构建选项,此模块支持各种套接字家族。
特定套接字对象所需的地址格式是根据创建套接字对象时指定的地址家族自动选择的。套接字地址的表示方式如下
绑定到文件系统节点的
AF_UNIX
套接字的地址表示为字符串,使用文件系统编码和'surrogateescape'
错误处理程序(请参阅 PEP 383)。Linux 抽象命名空间中的地址以带有初始空字节的 类字节对象 形式返回;请注意,此命名空间中的套接字可以与普通文件系统套接字通信,因此打算在 Linux 上运行的程序可能需要处理这两种类型的地址。字符串或类字节对象可以用作传递作为参数时的任何一种地址类型。版本 3.3 中的变化: 以前,
AF_UNIX
套接字路径假定使用 UTF-8 编码。版本 3.5 中的变化: 现在接受可写的 类字节对象。
AF_INET
地址家族使用对组(host, port)
,其中 host 是一个字符串,表示互联网域名表示法中的主机名(如'daring.cwi.nl'
)或 IPv4 地址(如'100.50.200.5'
),而 port 是一个整数。对于 IPv4 地址,可以使用两种特殊形式来代替主机地址:
''
表示INADDR_ANY
,用于绑定到所有接口,而字符串'<broadcast>'
表示INADDR_BROADCAST
。此行为与 IPv6 不兼容,因此,如果您打算在 Python 程序中支持 IPv6,则应避免使用这些形式。
对于
AF_INET6
地址家族,使用四元组(host, port, flowinfo, scope_id)
,其中 flowinfo 和 scope_id 分别表示 C 语言中struct sockaddr_in6
中的sin6_flowinfo
和sin6_scope_id
成员。对于socket
模块方法,为了向后兼容,可以省略 flowinfo 和 scope_id。但是请注意,省略 scope_id 可能会导致操作范围内的 IPv6 地址出现问题。版本 3.7 中的变化: 对于多播地址(scope_id 有意义),address 可能不包含
%scope_id
(或zone id
)部分。此信息是多余的,可以安全地省略(推荐)。AF_NETLINK
套接字表示为对组(pid, groups)
。可以使用
AF_TIPC
地址家族获得仅限 Linux 的 TIPC 支持。TIPC 是一种开放的、非基于 IP 的网络协议,专为在集群计算机环境中使用而设计。地址由元组表示,字段取决于地址类型。一般的元组形式为(addr_type, v1, v2, v3 [, scope])
,其中addr_type 是
TIPC_ADDR_NAMESEQ
、TIPC_ADDR_NAME
或TIPC_ADDR_ID
之一。scope 是
TIPC_ZONE_SCOPE
、TIPC_CLUSTER_SCOPE
和TIPC_NODE_SCOPE
之一。如果 addr_type 是
TIPC_ADDR_NAME
,则 v1 是服务器类型,v2 是端口标识符,v3 应为 0。如果 addr_type 是
TIPC_ADDR_NAMESEQ
,则 v1 是服务器类型,v2 是较低的端口号,v3 是较高的端口号。如果 addr_type 是
TIPC_ADDR_ID
,则 v1 是节点,v2 是引用,v3 应该设置为 0。
元组
(interface, )
用于AF_CAN
地址族,其中 interface 是一个表示网络接口名称的字符串,例如'can0'
。网络接口名称''
可用于接收来自该地址族所有网络接口的数据包。字符串或元组
(id, unit)
用于PF_SYSTEM
地址族的SYSPROTO_CONTROL
协议。字符串是使用动态分配 ID 的内核控件的名称。如果已知内核控件的 ID 和单元号,或者使用已注册的 ID,则可以使用该元组。3.3 版新增。
AF_BLUETOOTH
支持以下协议和地址格式BTPROTO_L2CAP
接受(bdaddr, psm)
,其中bdaddr
是字符串形式的蓝牙地址,psm
是一个整数。BTPROTO_RFCOMM
接受(bdaddr, channel)
,其中bdaddr
是字符串形式的蓝牙地址,channel
是一个整数。BTPROTO_HCI
接受(device_id,)
,其中device_id
是一个整数或包含接口蓝牙地址的字符串。(这取决于您的操作系统;NetBSD 和 DragonFlyBSD 需要蓝牙地址,而其他所有操作系统都需要整数。)在 3.2 版更改: 添加了对 NetBSD 和 DragonFlyBSD 的支持。
BTPROTO_SCO
接受bdaddr
,其中bdaddr
是一个包含字符串格式蓝牙地址的bytes
对象。(例如b'12:23:34:45:56:67'
)FreeBSD 不支持此协议。
AF_ALG
是一个仅限 Linux 的基于套接字的接口,用于与内核加密进行通信。算法套接字使用包含两到四个元素的元组进行配置(type, name [, feat [, mask]])
,其中type 是字符串形式的算法类型,例如
aead
、hash
、skcipher
或rng
。name 是字符串形式的算法名称和操作模式,例如
sha256
、hmac(sha256)
、cbc(aes)
或drbg_nopr_ctr_aes256
。feat 和 mask 是无符号 32 位整数。
可用性:Linux >= 2.6.38。
某些算法类型需要更新的内核。
3.6 版新增。
AF_VSOCK
允许虚拟机与其主机之间进行通信。套接字表示为(CID, port)
元组,其中上下文 ID 或 CID 和端口是整数。3.7 版新增。
AF_PACKET
是直接连接到网络设备的低级接口。地址由元组(ifname, proto[, pkttype[, hatype[, addr]]])
表示,其中ifname - 指定设备名称的字符串。
proto - 以太网协议号。可以是
ETH_P_ALL
以捕获所有协议,ETHERTYPE_* 常量 之一或任何其他以太网协议号。pkttype - 可选整数,指定数据包类型
PACKET_HOST
(默认值)- 寻址到本地主机的数据包。PACKET_BROADCAST
- 物理层广播数据包。PACKET_MULTICAST
- 发送到物理层多播地址的数据包。PACKET_OTHERHOST
- 发送到已在混杂模式下由设备驱动程序捕获的某个其他主机的数据包。PACKET_OUTGOING
- 源自本地主机并回环到数据包套接字的数据包。
hatype - 可选整数,指定 ARP 硬件地址类型。
addr - 可选的类字节对象,指定硬件物理地址,其解释取决于设备。
可用性:Linux >= 2.2。
AF_QIPCRTR
是一个仅限 Linux 的基于套接字的接口,用于与 Qualcomm 平台上协处理器上运行的服务进行通信。地址族表示为(node, port)
元组,其中 node 和 port 是非负整数。可用性:Linux >= 4.7。
3.8 版新增。
IPPROTO_UDPLITE
是 UDP 的一种变体,它允许您指定数据包的哪一部分包含校验和。它添加了两个您可以更改的套接字选项。self.setsockopt(IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV, length)
将更改传出数据包的哪一部分包含校验和,self.setsockopt(IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV, length)
将过滤掉数据覆盖范围太小的数据包。在这两种情况下,length
都应在range(8, 2**16, 8)
范围内。应该使用
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE)
(对于 IPv4)或socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE)
(对于 IPv6)构造此类套接字。可用性:Linux >= 2.6.20,FreeBSD >= 10.1
3.9 版新增。
AF_HYPERV
是一个仅限 Windows 的基于套接字的接口,用于与 Hyper-V 主机和来宾进行通信。地址族表示为(vm_id, service_id)
元组,其中vm_id
和service_id
是 UUID 字符串。vm_id
是虚拟机标识符,如果目标不是特定的虚拟机,则为一组已知的 VMID 值。在socket
上定义的已知 VMID 常量为:HV_GUID_ZERO
HV_GUID_BROADCAST
HV_GUID_WILDCARD
- 用于绑定自身并接受来自所有分区的连接。HV_GUID_CHILDREN
- 用于绑定自身并接受来自子分区的连接。HV_GUID_LOOPBACK
- 用作自身的地址目标。HV_GUID_PARENT
- 当用作绑定时,接受来自父分区的连接。当用作地址目标时,它将连接到父分区。
service_id
是已注册服务的标识符。版本 3.12 中新增。
如果在 IPv4/v6 套接字地址的“主机”部分使用主机名,则程序可能会表现出不确定的行为,因为 Python 使用从 DNS 解析返回的第一个地址。套接字地址将被解析为不同的实际 IPv4/v6 地址,具体取决于 DNS 解析的结果和/或主机配置。为了获得确定性行为,请在“主机”部分使用数字地址。
所有错误都会引发异常。可能会引发与无效参数类型和内存不足情况相关的常见异常。与套接字或地址语义相关的错误会引发 OSError
或其子类之一。
非阻塞模式通过 setblocking()
支持。基于超时的概括通过 settimeout()
支持。
模块内容¶
模块 socket
导出以下元素。
异常¶
- exception socket.herror¶
OSError
的子类,此异常针对地址相关的错误引发,例如,对于在 POSIX C API 中使用“h_errno”的函数,包括gethostbyname_ex()
和gethostbyaddr()
。随附的值是一个对(h_errno, string)
,表示库调用返回的错误。“h_errno”是一个数值,而“string”表示“h_errno”的描述,由 C 函数hstrerror()
返回。版本 3.3 中的变化: 此类已成为
OSError
的子类。
- exception socket.gaierror¶
OSError
的子类,此异常由getaddrinfo()
和getnameinfo()
针对地址相关的错误引发。随附的值是一个对(error, string)
,表示库调用返回的错误。“string”表示“error”的描述,由 C 函数gai_strerror()
返回。数字“error”值将与本模块中定义的EAI_*
常量之一匹配。版本 3.3 中的变化: 此类已成为
OSError
的子类。
- exception socket.timeout¶
TimeoutError
的已弃用别名。OSError
的子类,当在通过先前调用settimeout()
(或通过setdefaulttimeout()
隐式调用)启用了超时的套接字上发生超时时,会引发此异常。随附的值是一个字符串,其值当前始终为“timed out”。版本 3.3 中的变化: 此类已成为
OSError
的子类。版本 3.10 中的变化: 此类已成为
TimeoutError
的别名。
常量¶
AF_* 和 SOCK_* 常量现在是
AddressFamily
和SocketKind
IntEnum
集合。版本 3.4 中新增。
- socket.AF_UNIX¶
- socket.AF_INET¶
- socket.AF_INET6¶
这些常量表示地址(和协议)系列,用于
socket()
的第一个参数。如果未定义AF_UNIX
常量,则不支持此协议。根据系统的不同,可能会有更多可用的常量。
- socket.AF_UNSPEC¶
AF_UNSPEC
表示getaddrinfo()
应该返回可用于任何地址族(IPv4、IPv6 或任何其他地址族)的套接字地址。
- socket.SOCK_STREAM¶
- socket.SOCK_DGRAM¶
- socket.SOCK_RAW¶
- socket.SOCK_RDM¶
- socket.SOCK_SEQPACKET¶
这些常量表示套接字类型,用于
socket()
的第二个参数。根据系统的不同,可能会有更多可用的常量。(似乎只有SOCK_STREAM
和SOCK_DGRAM
通常有用。)
- socket.SOCK_CLOEXEC¶
- socket.SOCK_NONBLOCK¶
这两个常量(如果已定义)可以与套接字类型组合使用,并允许您原子地设置一些标志(从而避免可能的竞争条件和单独调用的需要)。
另请参阅
有关更详细的说明,请参阅安全文件描述符处理。
可用性:Linux >= 2.6.27。
3.2 版新增。
- SO_*
- socket.SOMAXCONN¶
- MSG_*
- SOL_*
- SCM_*
- IPPROTO_*
- IPPORT_*
- INADDR_*
- IP_*
- IPV6_*
- EAI_*
- AI_*
- NI_*
- TCP_*
套接字模块中还定义了许多此类形式的常量,这些常量在 Unix 套接字和/或 IP 协议的文档中有记录。它们通常用作套接字对象的
setsockopt()
和getsockopt()
方法的参数。在大多数情况下,只定义了在 Unix 头文件中定义的符号;对于少数符号,提供了默认值。在 3.6 版更改: 添加了
SO_DOMAIN
、SO_PROTOCOL
、SO_PEERSEC
、SO_PASSSEC
、TCP_USER_TIMEOUT
、TCP_CONGESTION
。在 3.6.5 版更改: 在 Windows 上,如果运行时 Windows 支持,则会出现
TCP_FASTOPEN
、TCP_KEEPCNT
。在 3.7 版更改: 添加了
TCP_NOTSENT_LOWAT
。在 Windows 上,如果运行时 Windows 支持,则会出现
TCP_KEEPIDLE
、TCP_KEEPINTVL
。在 3.10 版更改: 添加了
IP_RECVTOS
。添加了TCP_KEEPALIVE
。在 MacOS 上,此常量的使用方法与在 Linux 上使用TCP_KEEPIDLE
的方法相同。在 3.11 版更改: 添加了
TCP_CONNECTION_INFO
。在 MacOS 上,此常量的使用方法与在 Linux 和 BSD 上使用TCP_INFO
的方法相同。在 3.12 版更改: 添加了
SO_RTABLE
和SO_USER_COOKIE
。在 OpenBSD 和 FreeBSD 上,这些常量的使用方法分别与在 Linux 上使用SO_MARK
的方法相同。还添加了 Linux 中缺少的 TCP 套接字选项:TCP_MD5SIG
、TCP_THIN_LINEAR_TIMEOUTS
、TCP_THIN_DUPACK
、TCP_REPAIR
、TCP_REPAIR_QUEUE
、TCP_QUEUE_SEQ
、TCP_REPAIR_OPTIONS
、TCP_TIMESTAMP
、TCP_CC_INFO
、TCP_SAVE_SYN
、TCP_SAVED_SYN
、TCP_REPAIR_WINDOW
、TCP_FASTOPEN_CONNECT
、TCP_ULP
、TCP_MD5SIG_EXT
、TCP_FASTOPEN_KEY
、TCP_FASTOPEN_NO_COOKIE
、TCP_ZEROCOPY_RECEIVE
、TCP_INQ
、TCP_TX_DELAY
。添加了IP_PKTINFO
、IP_UNBLOCK_SOURCE
、IP_BLOCK_SOURCE
、IP_ADD_SOURCE_MEMBERSHIP
、IP_DROP_SOURCE_MEMBERSHIP
。
- socket.AF_CAN¶
- socket.PF_CAN¶
- SOL_CAN_*
- CAN_*
套接字模块中还定义了许多此类形式的常量,这些常量在 Linux 文档中有记录。
可用性:Linux >= 2.6.25,NetBSD >= 8。
3.3 版新增。
在 3.11 版更改: 添加了对 NetBSD 的支持。
- socket.CAN_BCM¶
- CAN_BCM_*
CAN_BCM 在 CAN 协议族中是广播管理器 (BCM) 协议。套接字模块中还定义了 Linux 文档中记录的广播管理器常量。
可用性:Linux >= 2.6.25。
注意
CAN_BCM_CAN_FD_FRAME
标志仅在 Linux >= 4.8 上可用。版本 3.4 中新增。
- socket.CAN_RAW_FD_FRAMES¶
在 CAN_RAW 套接字中启用 CAN FD 支持。默认情况下禁用此功能。这允许您的应用程序发送 CAN 和 CAN FD 帧;但是,从套接字读取数据时,您必须同时接受 CAN 和 CAN FD 帧。
此常量在 Linux 文档中有记录。
可用性:Linux >= 3.6。
3.5 版新增。
- socket.CAN_RAW_JOIN_FILTERS¶
加入应用的 CAN 过滤器,以便仅将与所有给定 CAN 过滤器匹配的 CAN 帧传递到用户空间。
此常量在 Linux 文档中有记录。
可用性:Linux >= 4.1。
3.9 版新增。
- socket.CAN_ISOTP¶
CAN_ISOTP 在 CAN 协议族中是 ISO-TP (ISO 15765-2) 协议。ISO-TP 常量,在 Linux 文档中有记录。
可用性:Linux >= 2.6.25。
3.7 版新增。
- socket.CAN_J1939¶
CAN_J1939 在 CAN 协议族中是 SAE J1939 协议。J1939 常量,在 Linux 文档中有记录。
可用性:Linux >= 5.4。
3.9 版新增。
- socket.AF_DIVERT¶
- socket.PF_DIVERT¶
这两个常量记录在 FreeBSD divert(4) 手册页中,也在 socket 模块中定义。
可用性:FreeBSD >= 14.0。
版本 3.12 中新增。
- socket.AF_PACKET¶
- socket.PF_PACKET¶
- PACKET_*
套接字模块中还定义了许多此类形式的常量,这些常量在 Linux 文档中有记录。
可用性:Linux >= 2.2。
- socket.ETH_P_ALL¶
ETH_P_ALL
可在socket
构造函数中用作AF_PACKET
族的 proto,以便捕获每个数据包,而不管协议是什么。更多信息请参阅 packet(7) 联机帮助页。
可用性:Linux。
版本 3.12 中新增。
- socket.AF_RDS¶
- socket.PF_RDS¶
- socket.SOL_RDS¶
- RDS_*
套接字模块中还定义了许多此类形式的常量,这些常量在 Linux 文档中有记录。
可用性:Linux >= 2.6.30。
3.3 版新增。
- socket.SIO_RCVALL¶
- socket.SIO_KEEPALIVE_VALS¶
- socket.SIO_LOOPBACK_FAST_PATH¶
- RCVALL_*
Windows WSAIoctl() 的常量。这些常量用作套接字对象的
ioctl()
方法的参数。在版本 3.6 中更改: 添加了
SIO_LOOPBACK_FAST_PATH
。
- TIPC_*
与 C 套接字 API 导出的常量相匹配的 TIPC 相关常量。有关更多信息,请参阅 TIPC 文档。
- socket.AF_VSOCK¶
- socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID¶
- VMADDR*
- SO_VM*
Linux 主机/客户机通信的常量。
可用性:Linux >= 4.8。
3.7 版新增。
- socket.has_ipv6¶
此常量包含一个布尔值,该值指示此平台上是否支持 IPv6。
- socket.BDADDR_ANY¶
- socket.BDADDR_LOCAL¶
这些是包含具有特殊含义的蓝牙地址的字符串常量。例如,
BDADDR_ANY
可用于在使用BTPROTO_RFCOMM
指定绑定套接字时指示任何地址。
- socket.HCI_FILTER¶
- socket.HCI_TIME_STAMP¶
- socket.HCI_DATA_DIR¶
与
BTPROTO_HCI
一起使用。NetBSD 或 DragonFlyBSD 不提供HCI_FILTER
。FreeBSD、NetBSD 或 DragonFlyBSD 不提供HCI_TIME_STAMP
和HCI_DATA_DIR
。
- socket.SCM_CREDS2¶
- socket.LOCAL_CREDS¶
- socket.LOCAL_CREDS_PERSISTENT¶
LOCAL_CREDS 和 LOCAL_CREDS_PERSISTENT 可以与 SOCK_DGRAM、SOCK_STREAM 套接字一起使用,相当于 Linux/DragonFlyBSD SO_PASSCRED,而 LOCAL_CREDS 在第一次读取时发送凭据,LOCAL_CREDS_PERSISTENT 为每次读取发送凭据,对于后者,必须将 SCM_CREDS2 用于消息类型。
在版本 3.11 中添加。
可用性:FreeBSD。
- socket.AF_HYPERV¶
- socket.HV_PROTOCOL_RAW¶
- socket.HVSOCKET_CONNECT_TIMEOUT¶
- socket.HVSOCKET_CONNECT_TIMEOUT_MAX¶
- socket.HVSOCKET_CONNECTED_SUSPEND¶
- socket.HVSOCKET_ADDRESS_FLAG_PASSTHRU¶
- socket.HV_GUID_ZERO¶
- socket.HV_GUID_WILDCARD¶
- socket.HV_GUID_BROADCAST¶
- socket.HV_GUID_CHILDREN¶
- socket.HV_GUID_LOOPBACK¶
- socket.HV_GUID_PARENT¶
用于主机/来宾通信的 Windows Hyper-V 套接字常量。
可用性:Windows。
版本 3.12 中新增。
函数¶
创建套接字¶
以下函数都创建 套接字对象。
- class socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)¶
使用给定的地址族、套接字类型和协议号创建一个新的套接字。地址族应该是
AF_INET
(默认值)、AF_INET6
、AF_UNIX
、AF_CAN
、AF_PACKET
或AF_RDS
。套接字类型应该是SOCK_STREAM
(默认值)、SOCK_DGRAM
、SOCK_RAW
或其他SOCK_
常量之一。协议号通常为零,可以省略,或者在地址族为AF_CAN
的情况下,协议应该是CAN_RAW
、CAN_BCM
、CAN_ISOTP
或CAN_J1939
之一。如果指定了 fileno,则会从指定的文件描述符中自动检测 family、type 和 proto 的值。可以通过使用显式的 family、type 或 proto 参数调用函数来覆盖自动检测。这只会影响 Python 如何表示例如
socket.getpeername()
的返回值,而不会影响实际的操作系统资源。与socket.fromfd()
不同,fileno 将返回相同的套接字,而不是副本。这可能有助于使用socket.close()
关闭分离的套接字。新创建的套接字是 不可继承的。
引发带有参数
self
、family
、type
、protocol
的 审计事件socket.__new__
。在 3.3 版本中更改: 添加了 AF_CAN 族。添加了 AF_RDS 族。
在 3.4 版本中更改: 添加了 CAN_BCM 协议。
在 3.4 版本中更改: 返回的套接字现在是不可继承的。
在 3.7 版本中更改: 添加了 CAN_ISOTP 协议。
在 3.7 版本中更改: 当将
SOCK_NONBLOCK
或SOCK_CLOEXEC
位标志应用于 type 时,它们会被清除,并且socket.type
将不会反映它们。它们仍然会被传递到底层的系统socket()
调用。因此,sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM | socket.SOCK_NONBLOCK)
在支持
SOCK_NONBLOCK
的操作系统上仍然会创建一个非阻塞套接字,但sock.type
将被设置为socket.SOCK_STREAM
。在 3.9 版本中更改: 添加了 CAN_J1939 协议。
在 3.10 版本中更改: 添加了 IPPROTO_MPTCP 协议。
- socket.socketpair([family[, type[, proto]]])¶
使用给定的地址族、套接字类型和协议号构建一对连接的套接字对象。地址族、套接字类型和协议号与上面的
socket()
函数相同。默认的地址族是AF_UNIX
(如果平台上定义了);否则,默认值为AF_INET
。新创建的套接字是 不可继承的。
版本 3.2 中的变化: 返回的套接字对象现在支持整个套接字 API,而不是一个子集。
版本 3.4 中的变化: 返回的套接字现在是不可继承的。
版本 3.5 中的变化: 添加了 Windows 支持。
- socket.create_connection(address, timeout=GLOBAL_DEFAULT, source_address=None, *, all_errors=False)¶
连接到 Internet 地址(一个 2 元组
(host, port)
)上监听的 TCP 服务,并返回套接字对象。这是一个比socket.connect()
更高级别的函数:如果 *host* 是一个非数字主机名,它将尝试为AF_INET
和AF_INET6
解析它,然后尝试依次连接到所有可能的地址,直到连接成功。这使得编写与 IPv4 和 IPv6 兼容的客户端变得容易。传递可选的 *timeout* 参数将在尝试连接之前设置套接字实例上的超时。如果没有提供 *timeout*,则使用由
getdefaulttimeout()
返回的全局默认超时设置。如果提供,*source_address* 必须是一个 2 元组
(host, port)
,用于在连接之前将套接字绑定到其源地址。如果主机或端口分别为 '' 或 0,则将使用操作系统默认行为。当无法创建连接时,会引发异常。默认情况下,它是列表中最后一个地址的异常。如果 *all_errors* 为
True
,则它是一个包含所有尝试错误的ExceptionGroup
。版本 3.2 中的变化: 添加了 *source_address*。
版本 3.11 中的变化: 添加了 *all_errors*。
- socket.create_server(address, *, family=AF_INET, backlog=None, reuse_port=False, dualstack_ipv6=False)¶
便捷函数,用于创建一个绑定到 *address*(一个 2 元组
(host, port)
)的 TCP 套接字并返回该套接字对象。*family* 应该是
AF_INET
或AF_INET6
。*backlog* 是传递给socket.listen()
的队列大小;如果没有指定,则选择一个默认的合理值。*reuse_port* 指示是否设置SO_REUSEPORT
套接字选项。如果 *dualstack_ipv6* 为真且平台支持,则套接字将能够接受 IPv4 和 IPv6 连接,否则将引发
ValueError
。大多数 POSIX 平台和 Windows 都应该支持此功能。启用此功能后,当发生 IPv4 连接时,socket.getpeername()
返回的地址将是一个表示为 IPv4 映射的 IPv6 地址的 IPv6 地址。如果 *dualstack_ipv6* 为假,它将在默认启用它的平台(例如 Linux)上显式禁用此功能。此参数可以与has_dualstack_ipv6()
结合使用import socket addr = ("", 8080) # all interfaces, port 8080 if socket.has_dualstack_ipv6(): s = socket.create_server(addr, family=socket.AF_INET6, dualstack_ipv6=True) else: s = socket.create_server(addr)
注意
在 POSIX 平台上,设置
SO_REUSEADDR
套接字选项是为了立即重用绑定到相同 *address* 并保持 TIME_WAIT 状态的先前套接字。3.8 版新增。
- socket.has_dualstack_ipv6()¶
如果平台支持创建可以同时处理 IPv4 和 IPv6 连接的 TCP 套接字,则返回
True
。3.8 版新增。
- socket.fromfd(fd, family, type, proto=0)¶
复制文件描述符 *fd*(文件对象的
fileno()
方法返回的整数),并从结果中构建一个套接字对象。地址族、套接字类型和协议号与上面的socket()
函数相同。文件描述符应该引用一个套接字,但这没有被检查 - 如果文件描述符无效,则对该对象的后续操作可能会失败。这个函数很少需要,但可以用来获取或设置传递给程序作为标准输入或输出的套接字上的套接字选项(例如由 Unix inet 守护进程启动的服务器)。假设套接字处于阻塞模式。新创建的套接字是 不可继承的。
在 3.4 版本中更改: 返回的套接字现在是不可继承的。
从
socket.share()
方法获得的数据实例化一个套接字。假设套接字处于阻塞模式。可用性:Windows。
3.3 版新增。
- socket.SocketType¶
这是一个 Python 类型对象,表示套接字对象类型。它与
type(socket(...))
相同。
其他函数¶
socket
模块还提供各种与网络相关的服务
- socket.close(fd)¶
关闭套接字文件描述符。这类似于
os.close()
,但用于套接字。在某些平台上(最明显的是 Windows),os.close()
不适用于套接字文件描述符。3.7 版新增。
- socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)¶
将 host/port 参数转换为 5 元组序列,其中包含创建连接到该服务的套接字所需的所有参数。host 是域名、IPv4/v6 地址的字符串表示形式或
None
。port 是字符串服务名称(例如'http'
)、数字端口号或None
。通过将None
作为 host 和 port 的值传递,您可以将NULL
传递给底层 C API。可以可选地指定 family、type 和 proto 参数,以缩小返回的地址列表的范围。为这些参数中的每一个传递零作为值将选择完整的结果范围。flags 参数可以是一个或多个
AI_*
常量,并且将影响结果的计算和返回方式。例如,AI_NUMERICHOST
将禁用域名解析,并且如果 host 是域名,则会引发错误。该函数返回一个 5 元组列表,其结构如下
(family, type, proto, canonname, sockaddr)
在这些元组中,family、type、proto 都是整数,旨在传递给
socket()
函数。如果AI_CANONNAME
是 flags 参数的一部分,则 canonname 将是一个表示 host 的规范名称的字符串;否则 canonname 将为空。sockaddr 是一个描述套接字地址的元组,其格式取决于返回的 family(AF_INET
的(address, port)
2 元组,AF_INET6
的(address, port, flowinfo, scope_id)
4 元组),旨在传递给socket.connect()
方法。引发带有参数
host
、port
、family
、type
、protocol
的 审计事件socket.getaddrinfo
。以下示例获取假设的 TCP 连接到端口 80 上的
example.org
的地址信息(如果未启用 IPv6,则结果在您的系统上可能会有所不同)>>> socket.getaddrinfo("example.org", 80, proto=socket.IPPROTO_TCP) [(socket.AF_INET6, socket.SOCK_STREAM, 6, '', ('2606:2800:220:1:248:1893:25c8:1946', 80, 0, 0)), (socket.AF_INET, socket.SOCK_STREAM, 6, '', ('93.184.216.34', 80))]
在 3.2 版更改: 现在可以使用关键字参数传递参数。
在 3.7 版更改: 对于 IPv6 多播地址,表示地址的字符串将不包含
%scope_id
部分。
- socket.getfqdn([name])¶
返回 name 的完全限定域名。如果省略 name 或为空,则将其解释为本地主机。为了找到完全限定名称,将检查
gethostbyaddr()
返回的主机名,然后检查主机的别名(如果可用)。选择第一个包含句点的名称。如果没有可用的完全限定域名并且提供了 name,则按原样返回。如果 name 为空或等于'0.0.0.0'
,则返回gethostname()
中的主机名。
- socket.gethostbyname(hostname)¶
将主机名转换为 IPv4 地址格式。IPv4 地址作为字符串返回,例如
'100.50.200.5'
。如果主机名本身就是一个 IPv4 地址,则按原样返回。有关更完整的接口,请参阅gethostbyname_ex()
。gethostbyname()
不支持 IPv6 名称解析,应改用getaddrinfo()
来获得 IPv4/v6 双栈支持。引发带有参数
hostname
的 审计事件socket.gethostbyname
。可用性:非 WASI。
- socket.gethostbyname_ex(hostname)¶
将主机名转换为 IPv4 地址格式,扩展接口。返回一个 3 元组
(hostname, aliaslist, ipaddrlist)
,其中 hostname 是主机的首选主机名,aliaslist 是同一地址的备用主机名列表(可能为空),ipaddrlist 是同一主机上同一接口的 IPv4 地址列表(通常但并非总是单个地址)。gethostbyname_ex()
不支持 IPv6 名称解析,应改用getaddrinfo()
来获得 IPv4/v6 双栈支持。引发带有参数
hostname
的 审计事件socket.gethostbyname
。可用性:非 WASI。
- socket.gethostname()¶
返回一个字符串,其中包含当前正在执行 Python 解释器的机器的主机名。
引发不带参数的 审计事件
socket.gethostname
。注意:
gethostname()
并不总是返回完全限定域名;为此,请使用getfqdn()
。可用性:非 WASI。
- socket.gethostbyaddr(ip_address)¶
返回一个三元组
(hostname, aliaslist, ipaddrlist)
,其中 hostname 是响应给定 ip_address 的主主机名,aliaslist 是同一地址的备用主机名列表(可能为空),ipaddrlist 是同一主机上同一接口的 IPv4/v6 地址列表(很可能只包含一个地址)。要查找完全限定域名,请使用函数getfqdn()
。gethostbyaddr()
支持 IPv4 和 IPv6。使用参数
ip_address
引发 审计事件socket.gethostbyaddr
。可用性:非 WASI。
- socket.getnameinfo(sockaddr, flags)¶
将套接字地址 sockaddr 转换为一个二元组
(host, port)
。根据 flags 的设置,结果可以在 host 中包含完全限定域名或数字地址表示。类似地,port 可以包含字符串端口名或数字端口号。对于 IPv6 地址,如果 sockaddr 包含有效的 scope_id,则
%scope_id
会附加到主机部分。通常这发生在多播地址上。有关 flags 的更多信息,请参阅 getnameinfo(3)。
使用参数
sockaddr
引发 审计事件socket.getnameinfo
。可用性:非 WASI。
- socket.getprotobyname(protocolname)¶
将互联网协议名称(例如,
'icmp'
)转换为适合作为socket()
函数的(可选)第三个参数传递的常量。这通常只在以“原始”模式(SOCK_RAW
)打开的套接字中需要;对于正常的套接字模式,如果省略协议或协议为零,则会自动选择正确的协议。可用性:非 WASI。
- socket.getservbyname(servicename[, protocolname])¶
将互联网服务名称和协议名称转换为该服务的端口号。可选的协议名称(如果给出)应为
'tcp'
或'udp'
,否则任何协议都将匹配。使用参数
servicename
、protocolname
引发 审计事件socket.getservbyname
。可用性:非 WASI。
- socket.getservbyport(port[, protocolname])¶
将互联网端口号和协议名称转换为该服务的名称。可选的协议名称(如果给出)应为
'tcp'
或'udp'
,否则任何协议都将匹配。使用参数
port
、protocolname
引发 审计事件socket.getservbyport
。可用性:非 WASI。
- socket.ntohl(x)¶
将 32 位正整数从网络字节序转换为主机字节序。在主机字节序与网络字节序相同的机器上,这是无操作的;否则,它执行 4 字节交换操作。
- socket.ntohs(x)¶
将 16 位正整数从网络字节序转换为主机字节序。在主机字节序与网络字节序相同的机器上,这是无操作的;否则,它执行 2 字节交换操作。
在 3.10 版更改: 如果 x 不适合 16 位无符号整数,则引发
OverflowError
。
- socket.htonl(x)¶
将 32 位正整数从主机字节序转换为网络字节序。在主机字节序与网络字节序相同的机器上,这是无操作的;否则,它执行 4 字节交换操作。
- socket.htons(x)¶
将 16 位正整数从主机字节序转换为网络字节序。在主机字节序与网络字节序相同的机器上,这是无操作的;否则,它执行 2 字节交换操作。
在 3.10 版更改: 如果 x 不适合 16 位无符号整数,则引发
OverflowError
。
- socket.inet_aton(ip_string)¶
将 IPv4 地址从点分十进制字符串格式(例如,“123.45.67.89”)转换为 32 位打包二进制格式,作为一个长度为四个字符的字节对象。这在与使用标准 C 库并需要
in_addr
类型对象的程序进行交互时非常有用,in_addr
是此函数返回的 32 位打包二进制的 C 类型。inet_aton()
也接受少于三个点的字符串;有关详细信息,请参阅 Unix 手册页 inet(3)。如果传递给此函数的 IPv4 地址字符串无效,则会引发
OSError
。请注意,究竟什么是有效的取决于inet_aton()
的底层 C 实现。inet_aton()
不支持 IPv6,应使用inet_pton()
来代替以获得 IPv4/v6 双栈支持。
- socket.inet_ntoa(packed_ip)¶
将 32 位打包 IPv4 地址(一个长度为 4 字节的类字节对象)转换为其标准的点分十进制字符串表示形式(例如,“123.45.67.89”)。当与使用标准 C 库并需要
in_addr
类型对象的程序进行交互时,这非常有用,in_addr
是此函数作为参数的 32 位打包二进制数据的 C 类型。如果传递给此函数的字节序列长度不完全为 4 个字节,则会引发
OSError
。inet_ntoa()
不支持 IPv6,对于 IPv4/v6 双栈支持,应改用inet_ntop()
。版本 3.5 中的变化: 现在接受可写的 类字节对象。
- socket.inet_pton(address_family, ip_string)¶
将 IP 地址从其特定于系列的字符串格式转换为打包的二进制格式。当库或网络协议调用
in_addr
(类似于inet_aton()
)或in6_addr
类型的对象时,inet_pton()
非常有用。address_family 支持的值当前为
AF_INET
和AF_INET6
。如果 IP 地址字符串 ip_string 无效,则会引发OSError
。请注意,确切的有效值取决于 address_family 的值和inet_pton()
的底层实现。可用性:Unix、Windows。
版本 3.4 中的变化: 添加了 Windows 支持
- socket.inet_ntop(address_family, packed_ip)¶
将打包的 IP 地址(具有一定字节数的类字节对象)转换为其标准的、特定于系列的字符串表示形式(例如,
'7.10.0.5'
或'5aef:2b::8'
)。当库或网络协议返回in_addr
(类似于inet_ntoa()
)或in6_addr
类型的对象时,inet_ntop()
非常有用。address_family 支持的值当前为
AF_INET
和AF_INET6
。如果字节对象 packed_ip 的长度与指定的地址系列不匹配,则会引发ValueError
。对于调用inet_ntop()
时出现的错误,会引发OSError
。可用性:Unix、Windows。
版本 3.4 中的变化: 添加了 Windows 支持
版本 3.5 中的变化: 现在接受可写的 类字节对象。
- socket.CMSG_LEN(length)¶
返回辅助数据项的总长度(不包括尾随填充),该辅助数据项具有给定 length 的关联数据。此值通常可以用作
recvmsg()
的缓冲区大小,以接收单个辅助数据项,但 RFC 3542 要求可移植应用程序使用CMSG_SPACE()
,因此即使该项是缓冲区中的最后一项,也要包含填充空间。如果 length 超出允许的值范围,则引发OverflowError
。可用性:Unix,非 Emscripten,非 WASI。
大多数 Unix 平台。
3.3 版新增。
- socket.CMSG_SPACE(length)¶
返回
recvmsg()
接收具有给定 length 的关联数据的辅助数据项所需的缓冲区大小,以及任何尾随填充。接收多个项目所需的缓冲区空间是其关联数据长度的CMSG_SPACE()
值之和。如果 length 超出允许的值范围,则引发OverflowError
。请注意,某些系统可能支持辅助数据,但不提供此函数。另请注意,使用此函数的结果设置缓冲区大小可能无法精确限制可接收的辅助数据量,因为其他数据可能能够放入填充区域。
可用性:Unix,非 Emscripten,非 WASI。
大多数 Unix 平台。
3.3 版新增。
- socket.getdefaulttimeout()¶
返回新套接字对象的默认超时时间(以秒为单位,浮点数)。值为
None
表示新套接字对象没有超时。首次导入套接字模块时,默认值为None
。
- socket.setdefaulttimeout(timeout)¶
设置新套接字对象的默认超时时间(以秒为单位,浮点数)。首次导入套接字模块时,默认值为
None
。有关可能的值及其各自含义,请参阅settimeout()
。
- socket.sethostname(name)¶
将机器的主机名设置为 name。如果您没有足够的权限,这将引发
OSError
。引发带有参数
name
的 审计事件socket.sethostname
。可用性:Unix。
3.3 版新增。
- socket.if_nameindex()¶
返回网络接口信息列表(索引 int,名称字符串)元组。如果系统调用失败,则返回
OSError
。可用性:Unix、Windows,不支持 Emscripten 和 WASI。
3.3 版新增。
在 3.8 版更改: 添加了 Windows 支持。
注意
在 Windows 上,网络接口在不同的上下文中具有不同的名称(所有名称均为示例)
UUID:
{FB605B73-AAC2-49A6-9A2F-25416AEA0573}
名称:
ethernet_32770
友好名称:
vEthernet (nat)
描述:
Hyper-V 虚拟 以太网 适配器
此函数从列表中返回第二种形式的名称,在本例中为
ethernet_32770
。
- socket.if_nametoindex(if_name)¶
返回与接口名称对应的网络接口索引号。如果不存在具有给定名称的接口,则返回
OSError
。可用性:Unix、Windows,不支持 Emscripten 和 WASI。
3.3 版新增。
在 3.8 版更改: 添加了 Windows 支持。
另请参阅
“接口名称”是
if_nameindex()
中记录的名称。
- socket.if_indextoname(if_index)¶
返回与接口索引号对应的网络接口名称。如果不存在具有给定索引的接口,则返回
OSError
。可用性:Unix、Windows,不支持 Emscripten 和 WASI。
3.3 版新增。
在 3.8 版更改: 添加了 Windows 支持。
另请参阅
“接口名称”是
if_nameindex()
中记录的名称。
套接字对象¶
套接字对象具有以下方法。除了 makefile()
之外,这些方法对应于适用于套接字的 Unix 系统调用。
- socket.accept()¶
接受连接。套接字必须绑定到地址并侦听连接。返回值是一个对
(conn, address)
,其中 conn 是一个可用于在连接上发送和接收数据的 新 套接字对象,而 address 是绑定到连接另一端套接字的地址。新创建的套接字是 不可继承的。
在 3.4 版更改: 套接字现在是不可继承的。
在 3.5 版更改: 如果系统调用被中断并且信号处理程序没有引发异常,该方法现在会重试系统调用,而不是引发
InterruptedError
异常(有关基本原理,请参阅 PEP 475)。
- socket.bind(address)¶
将套接字绑定到 address。套接字不得已绑定。(address 的格式取决于地址系列 - 请参见上文。)
引发带有参数
self
、address
的 审计事件socket.bind
。可用性:非 WASI。
- socket.close()¶
将套接字标记为已关闭。当
makefile()
中的所有文件对象都被关闭时,底层系统资源(例如文件描述符)也会被关闭。一旦发生这种情况,套接字对象上的所有未来操作都将失败。远程端将不再接收数据(在排队数据刷新之后)。套接字在被垃圾回收时会自动关闭,但建议显式地
close()
关闭它们,或者在它们周围使用with
语句。在 3.6 版更改: 如果在进行底层
close()
调用时发生错误,现在会引发OSError
。注意
close()
释放与连接关联的资源,但不一定会立即关闭连接。如果要及时关闭连接,请在close()
之前调用shutdown()
。
- socket.connect(address)¶
连接到 address 处的远程套接字。(address 的格式取决于地址族 - 见上文。)
如果连接被信号中断,该方法将等待连接完成,或者在超时时引发
TimeoutError
,前提是信号处理程序没有引发异常并且套接字处于阻塞状态或具有超时。对于非阻塞套接字,如果连接被信号中断(或信号处理程序引发的异常),该方法将引发InterruptedError
异常。引发带有参数
self
、address
的 审计事件socket.connect
。在 3.5 版更改: 如果连接被信号中断,该方法现在将等待连接完成,而不是引发
InterruptedError
异常,前提是信号处理程序没有引发异常并且套接字处于阻塞状态或具有超时(有关基本原理,请参阅 PEP 475)。可用性:非 WASI。
- socket.connect_ex(address)¶
类似于
connect(address)
,但返回错误指示器而不是为 C 级connect()
调用返回的错误引发异常(其他问题,例如“找不到主机”,仍然可以引发异常)。如果操作成功,则错误指示器为0
,否则为errno
变量的值。这对于支持例如异步连接很有用。引发带有参数
self
、address
的 审计事件socket.connect
。可用性:非 WASI。
- socket.detach()¶
将套接字对象置于关闭状态,而不实际关闭底层文件描述符。文件描述符将被返回,并且可以重新用于其他目的。
3.2 版新增。
- socket.fileno()¶
返回套接字的文件描述符(一个小整数),如果失败则返回 -1。这对于
select.select()
很有用。在 Windows 下,此方法返回的小整数不能在可以使用文件描述符的地方使用(例如
os.fdopen()
)。Unix 没有此限制。
- socket.get_inheritable()¶
获取套接字文件描述符或套接字句柄的 可继承标志:如果套接字可以在子进程中继承,则为
True
,如果不能继承,则为False
。版本 3.4 中新增。
- socket.getpeername()¶
返回套接字连接到的远程地址。例如,这对于找出远程 IPv4/v6 套接字的端口号很有用。(返回的地址格式取决于地址族 - 见上文。)某些系统不支持此功能。
- socket.getsockname()¶
返回套接字自身的地址。例如,这对于找出 IPv4/v6 套接字的端口号很有用。(返回的地址格式取决于地址族 - 见上文。)
- socket.getsockopt(level, optname[, buflen])¶
返回给定套接字选项的值(请参阅 Unix 联机帮助页 getsockopt(2))。所需的符号常量(SO_* 等)在此模块中定义。如果省略 buflen,则假定为整数选项,并且该函数返回其整数值。如果存在 buflen,则它指定用于接收选项的缓冲区的最大长度,并且此缓冲区作为字节对象返回。由调用者负责解码缓冲区的内容(有关解码编码为字节字符串的 C 结构的方法,请参阅可选的内置模块
struct
)。可用性:非 WASI。
- socket.getblocking()¶
如果套接字处于阻塞模式,则返回
True
,如果处于非阻塞模式,则返回False
。这等效于检查
socket.gettimeout() != 0
。3.7 版新增。
- socket.gettimeout()¶
返回与套接字操作关联的超时时间(以秒为单位的浮点数),如果没有设置超时,则返回
None
。这反映了对setblocking()
或settimeout()
的最后一次调用。
- socket.ioctl(control, option)¶
- 平台:
Windows
ioctl()
方法是 WSAIoctl 系统接口的有限接口。有关详细信息,请参阅 Win32 文档。在其他平台上,可以使用通用的
fcntl.fcntl()
和fcntl.ioctl()
函数;它们接受一个套接字对象作为第一个参数。目前仅支持以下控制代码:
SIO_RCVALL
、SIO_KEEPALIVE_VALS
和SIO_LOOPBACK_FAST_PATH
。在版本 3.6 中更改: 添加了
SIO_LOOPBACK_FAST_PATH
。
- socket.listen([backlog])¶
使服务器能够接受连接。如果指定了 *backlog*,则它必须至少为 0(如果它更低,则将其设置为 0);它指定系统在拒绝新连接之前允许的未接受连接数。如果未指定,则选择默认的合理值。
可用性:非 WASI。
版本 3.5 中的变化: *backlog* 参数现在是可选的。
- socket.makefile(mode='r', buffering=None, *, encoding=None, errors=None, newline=None)¶
返回与套接字关联的 文件对象。确切的返回类型取决于提供给
makefile()
的参数。这些参数的解释方式与内置open()
函数相同,但唯一支持的 *mode* 值是'r'
(默认)、'w'
、'b'
或它们的组合。套接字必须处于阻塞模式;它可以有一个超时,但如果发生超时,文件对象的内部缓冲区可能会最终处于不一致的状态。
关闭
makefile()
返回的文件对象不会关闭原始套接字,除非所有其他文件对象都已关闭并且已在套接字对象上调用了socket.close()
。注意
在 Windows 上,由
makefile()
创建的类文件对象不能在需要具有文件描述符的文件对象的地方使用,例如subprocess.Popen()
的流参数。
- socket.recv(bufsize[, flags])¶
从套接字接收数据。返回值是一个表示接收到的数据的字节对象。一次要接收的最大数据量由 *bufsize* 指定。返回的空字节对象表示客户端已断开连接。有关可选参数 *flags* 的含义,请参阅 Unix 手册页 recv(2);它默认为零。
注意
为了最好地匹配硬件和网络的实际情况,*bufsize* 的值应该是一个相对较小的 2 的幂,例如 4096。
版本 3.5 中的变化: 如果系统调用被中断并且信号处理程序没有引发异常,该方法现在会重试系统调用,而不是引发
InterruptedError
异常(有关基本原理,请参阅 PEP 475)。
- socket.recvfrom(bufsize[, flags])¶
从套接字接收数据。返回值是一个对
(bytes, address)
,其中 *bytes* 是一个表示接收到的数据的字节对象,而 *address* 是发送数据的套接字的地址。有关可选参数 *flags* 的含义,请参阅 Unix 手册页 recv(2);它默认为零。(*address* 的格式取决于地址系列 - 见上文。)版本 3.5 中的变化: 如果系统调用被中断并且信号处理程序没有引发异常,该方法现在会重试系统调用,而不是引发
InterruptedError
异常(有关基本原理,请参阅 PEP 475)。版本 3.7 中的变化: 对于多播 IPv6 地址,*address* 的第一项不再包含
%scope_id
部分。要获取完整的 IPv6 地址,请使用getnameinfo()
。
- socket.recvmsg(bufsize[, ancbufsize[, flags]])¶
从套接字接收普通数据(最多 bufsize 字节)和辅助数据。ancbufsize 参数设置用于接收辅助数据的内部缓冲区的大小(以字节为单位);它默认为 0,表示不接收辅助数据。可以使用
CMSG_SPACE()
或CMSG_LEN()
计算辅助数据的适当缓冲区大小,不适合缓冲区的项目可能会被截断或丢弃。flags 参数默认为 0,其含义与recv()
相同。返回值是一个 4 元组:
(data, ancdata, msg_flags, address)
。data 项目是一个bytes
对象,其中包含接收到的非辅助数据。ancdata 项目是一个包含零个或多个元组(cmsg_level, cmsg_type, cmsg_data)
的列表,表示接收到的辅助数据(控制消息):cmsg_level 和 cmsg_type 是分别指定协议级别和协议特定类型的整数,而 cmsg_data 是一个包含关联数据的bytes
对象。msg_flags 项目是指示接收到的消息条件的各种标志的按位或;有关详细信息,请参阅您的系统文档。如果接收套接字未连接,则 address 是发送套接字的地址(如果可用);否则,其值未指定。在某些系统上,
sendmsg()
和recvmsg()
可用于通过AF_UNIX
套接字在进程之间传递文件描述符。当使用此功能时(通常仅限于SOCK_STREAM
套接字),recvmsg()
将在其辅助数据中返回形式为(socket.SOL_SOCKET, socket.SCM_RIGHTS, fds)
的项目,其中 fds 是一个bytes
对象,表示新的文件描述符,作为本机 C int 类型的二进制数组。如果在系统调用返回后recvmsg()
引发异常,它将首先尝试关闭通过此机制接收到的任何文件描述符。某些系统不指示仅部分接收到的辅助数据项的截断长度。如果某个项目似乎超出了缓冲区的末尾,则
recvmsg()
将发出RuntimeWarning
,并将返回其在缓冲区内的部分(前提是它在关联数据的开头之前没有被截断)。在支持
SCM_RIGHTS
机制的系统上,以下函数将接收最多 maxfds 个文件描述符,返回消息数据和一个包含描述符的列表(同时忽略意外情况,例如接收到不相关的控制消息)。另请参阅sendmsg()
。import socket, array def recv_fds(sock, msglen, maxfds): fds = array.array("i") # Array of ints msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(maxfds * fds.itemsize)) for cmsg_level, cmsg_type, cmsg_data in ancdata: if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS: # Append data, ignoring any truncated integers at the end. fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) return msg, list(fds)
可用性:Unix。
大多数 Unix 平台。
3.3 版新增。
版本 3.5 中的变化: 如果系统调用被中断并且信号处理程序没有引发异常,该方法现在会重试系统调用,而不是引发
InterruptedError
异常(有关基本原理,请参阅 PEP 475)。
- socket.recvmsg_into(buffers[, ancbufsize[, flags]])¶
从套接字接收普通数据和辅助数据,其行为与
recvmsg()
相同,但将非辅助数据分散到一系列缓冲区中,而不是返回新的字节对象。buffers 参数必须是导出可写缓冲区的对象的迭代器(例如bytearray
对象);这些缓冲区将填充连续的非辅助数据块,直到所有数据都已写入或没有更多缓冲区为止。操作系统可能会对可以使用的缓冲区数量设置限制(sysconf()
值SC_IOV_MAX
)。ancbufsize 和 flags 参数的含义与recvmsg()
相同。返回值是一个 4 元组:
(nbytes, ancdata, msg_flags, address)
,其中 nbytes 是写入缓冲区的非辅助数据的总字节数,而 ancdata、msg_flags 和 address 与recvmsg()
相同。示例
>>> import socket >>> s1, s2 = socket.socketpair() >>> b1 = bytearray(b'----') >>> b2 = bytearray(b'0123456789') >>> b3 = bytearray(b'--------------') >>> s1.send(b'Mary had a little lamb') 22 >>> s2.recvmsg_into([b1, memoryview(b2)[2:9], b3]) (22, [], 0, None) >>> [b1, b2, b3] [bytearray(b'Mary'), bytearray(b'01 had a 9'), bytearray(b'little lamb---')]
可用性:Unix。
大多数 Unix 平台。
3.3 版新增。
- socket.recvfrom_into(buffer[, nbytes[, flags]])¶
从套接字接收数据,将其写入 buffer 中,而不是创建新的字节串。返回值是一个对
(nbytes, address)
,其中 nbytes 是接收到的字节数,address 是发送数据的套接字的地址。有关可选参数 flags 的含义,请参阅 Unix 手册页 recv(2);它默认为零。(address 的格式取决于地址族 - 见上文。)
- socket.recv_into(buffer[, nbytes[, flags]])¶
从套接字接收最多 nbytes 个字节,将数据存储到缓冲区中,而不是创建新的字节串。如果未指定 nbytes(或为 0),则接收最多可用于给定缓冲区的大小。返回接收到的字节数。有关可选参数 flags 的含义,请参阅 Unix 手册页 recv(2);它默认为零。
- socket.send(bytes[, flags])¶
向套接字发送数据。套接字必须连接到远程套接字。可选的 flags 参数与上面
recv()
中的含义相同。返回发送的字节数。应用程序负责检查是否已发送所有数据;如果仅传输了部分数据,则应用程序需要尝试传送剩余数据。有关此主题的更多信息,请参阅 套接字编程指南。版本 3.5 中的变化: 如果系统调用被中断且信号处理程序未引发异常,该方法现在将重试系统调用,而不是引发
InterruptedError
异常(有关基本原理,请参阅 PEP 475)。
- socket.sendall(bytes[, flags])¶
向套接字发送数据。套接字必须连接到远程套接字。可选的 flags 参数与上面
recv()
中的含义相同。与send()
不同,此方法会继续从 bytes 发送数据,直到所有数据都已发送或发生错误。成功时返回None
。发生错误时,会引发异常,并且无法确定成功发送了多少数据(如果有)。版本 3.5 中的变化: 每次成功发送数据时,不再重置套接字超时。套接字超时现在是发送所有数据的最大总持续时间。
版本 3.5 中的变化: 如果系统调用被中断且信号处理程序未引发异常,该方法现在将重试系统调用,而不是引发
InterruptedError
异常(有关基本原理,请参阅 PEP 475)。
- socket.sendto(bytes, address)¶
- socket.sendto(bytes, flags, address)
向套接字发送数据。套接字不应连接到远程套接字,因为目标套接字由 address 指定。可选的 flags 参数与上面
recv()
中的含义相同。返回发送的字节数。(address 的格式取决于地址系列 - 请参见上文。)引发带有参数
self
、address
的 审计事件socket.sendto
。版本 3.5 中的变化: 如果系统调用被中断且信号处理程序未引发异常,该方法现在将重试系统调用,而不是引发
InterruptedError
异常(有关基本原理,请参阅 PEP 475)。
- socket.sendmsg(buffers[, ancdata[, flags[, address]]])¶
向套接字发送普通数据和辅助数据,从一系列缓冲区收集非辅助数据并将其连接成单个消息。buffers 参数将非辅助数据指定为 类字节对象(例如
bytes
对象)的可迭代对象;操作系统可能会对可使用的缓冲区数量设置限制(sysconf()
值SC_IOV_MAX
)。ancdata 参数将辅助数据(控制消息)指定为零个或多个元组(cmsg_level, cmsg_type, cmsg_data)
的可迭代对象,其中 cmsg_level 和 cmsg_type 是分别指定协议级别和协议特定类型的整数,而 cmsg_data 是保存关联数据的类字节对象。请注意,某些系统(特别是没有CMSG_SPACE()
的系统)可能仅支持每次调用发送一条控制消息。flags 参数默认为 0,其含义与send()
相同。如果提供了 address 并且它不是None
,则它会为消息设置目标地址。返回值是发送的非辅助数据的字节数。以下函数在支持
SCM_RIGHTS
机制的系统上,通过AF_UNIX
套接字发送文件描述符列表 fds。另请参阅recvmsg()
。import socket, array def send_fds(sock, msg, fds): return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, array.array("i", fds))])
可用性:Unix,而非 WASI。
大多数 Unix 平台。
引发带有参数
self
、address
的 审计事件socket.sendmsg
。3.3 版新增。
版本 3.5 中的变化: 如果系统调用被中断且信号处理程序未引发异常,该方法现在将重试系统调用,而不是引发
InterruptedError
异常(有关基本原理,请参阅 PEP 475)。
- socket.sendmsg_afalg([msg, ]*, op[, iv[, assoclen[, flags]]])¶
AF_ALG
套接字的sendmsg()
的专用版本。为AF_ALG
套接字设置模式、IV、AEAD 关联数据长度和标志。可用性:Linux >= 2.6.38。
3.6 版新增。
- socket.sendfile(file, offset=0, count=None)¶
使用高性能的
os.sendfile
发送文件直到达到 EOF,并返回已发送的字节总数。file 必须是以二进制模式打开的常规文件对象。如果os.sendfile
不可用(例如 Windows)或 file 不是常规文件,则将使用send()
代替。offset 指示从何处开始读取文件。如果指定了 count,则它是指要传输的总字节数,而不是发送文件直到达到 EOF。文件位置会在返回时更新,或者在发生错误时也会更新,在这种情况下,可以使用file.tell()
来确定已发送的字节数。套接字必须是SOCK_STREAM
类型。不支持非阻塞套接字。3.5 版新增。
- socket.setblocking(flag)¶
设置套接字的阻塞或非阻塞模式:如果 flag 为 false,则将套接字设置为非阻塞模式,否则设置为阻塞模式。
此方法是某些
settimeout()
调用的简写形式sock.setblocking(True)
等效于sock.settimeout(None)
sock.setblocking(False)
等效于sock.settimeout(0.0)
版本 3.7 中的变化: 该方法不再在
socket.type
上应用SOCK_NONBLOCK
标志。
- socket.settimeout(value)¶
设置阻塞套接字操作的超时。value 参数可以是非负浮点数(表示秒数)或
None
。如果给定非零值,则如果在操作完成之前已过超时时间 value,则后续套接字操作将引发timeout
异常。如果给定零,则套接字将置于非阻塞模式。如果给定None
,则套接字将置于阻塞模式。有关更多信息,请参阅 有关套接字超时的说明。
版本 3.7 中的变化: 该方法不再在
socket.type
上切换SOCK_NONBLOCK
标志。
- socket.setsockopt(level, optname, value: buffer)
- socket.setsockopt(level, optname, None, optlen: int)
设置给定套接字选项的值(请参阅 Unix 联机帮助页 setsockopt(2))。所需的符号常量在此模块中定义(SO_* 等 <socket-unix-constants>)。该值可以是整数、
None
或表示缓冲区的 类字节对象。在后一种情况下,由调用者负责确保字节串包含正确的位(有关将 C 结构编码为字节串的方法,请参阅可选的内置模块struct
)。当 value 设置为None
时,需要 optlen 参数。这等效于使用optval=NULL
和optlen=optlen
调用setsockopt()
C 函数。版本 3.5 中的变化: 现在接受可写的 类字节对象。
版本 3.6 中的变化: 添加了 setsockopt(level, optname, None, optlen: int) 形式。
可用性:非 WASI。
- socket.shutdown(how)¶
关闭连接的一半或两半。如果 how 为
SHUT_RD
,则不允许进一步接收。如果 how 为SHUT_WR
,则不允许进一步发送。如果 how 为SHUT_RDWR
,则不允许进一步发送和接收。可用性:非 WASI。
复制套接字并准备与目标进程共享。必须为目标进程提供 process_id。然后,可以使用某种形式的进程间通信将生成的字节对象传递给目标进程,并且可以使用
fromshare()
在目标进程中重新创建套接字。调用此方法后,可以安全地关闭套接字,因为操作系统已经为目标进程复制了它。可用性:Windows。
3.3 版新增。
请注意,没有 read()
或 write()
方法;请使用不带 flags 参数的 recv()
和 send()
方法。
套接字对象还具有以下(只读)属性,这些属性对应于传递给 socket
构造函数的值。
- socket.family¶
套接字家族。
- socket.type¶
套接字类型。
- socket.proto¶
套接字协议。
关于套接字超时的说明¶
套接字对象可以处于以下三种模式之一:阻塞、非阻塞或超时。默认情况下,套接字始终在阻塞模式下创建,但这可以通过调用 setdefaulttimeout()
来更改。
在*阻塞模式*下,操作会一直阻塞,直到完成或系统返回错误(例如连接超时)。
在*非阻塞模式*下,如果操作无法立即完成,则会失败(出现一个不幸依赖于系统的错误):可以使用
select
模块中的函数来了解套接字何时以及是否可用于读取或写入。在*超时模式*下,如果操作无法在为套接字指定的超时时间内完成(它们会引发
timeout
异常)或系统返回错误,则操作会失败。
注意
在操作系统级别,*超时模式*下的套接字在内部设置为非阻塞模式。此外,阻塞和超时模式在文件描述符和引用同一网络端点的套接字对象之间共享。如果您决定使用套接字的 fileno()
,则此实现细节可能会产生明显的后果。
超时和 connect
方法¶
connect()
操作也受超时设置的约束,通常建议在调用 connect()
之前调用 settimeout()
或将超时参数传递给 create_connection()
。但是,无论任何 Python 套接字超时设置如何,系统网络堆栈也可能会返回其自身的连接超时错误。
超时和 accept
方法¶
如果 getdefaulttimeout()
不是 None
,则 accept()
方法返回的套接字将继承该超时。否则,行为取决于侦听套接字的设置
示例¶
以下是使用 TCP/IP 协议的四个最小示例程序:一个服务器回显它接收到的所有数据(仅服务一个客户端),以及一个使用它的客户端。请注意,服务器必须执行序列 socket()
、bind()
、listen()
、accept()
(可能重复 accept()
以服务多个客户端),而客户端只需要序列 socket()
、connect()
。另请注意,服务器不在其侦听的套接字上执行 sendall()
/recv()
,而是在 accept()
返回的新套接字上执行。
前两个示例仅支持 IPv4。
# Echo server program
import socket
HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
# Echo client program
import socket
HOST = 'daring.cwi.nl' # The remote host
PORT = 50007 # The same port as used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', repr(data))
接下来的两个示例与上面的两个示例相同,但同时支持 IPv4 和 IPv6。服务器端将侦听第一个可用的地址家族(它应该同时侦听两者)。在大多数支持 IPv6 的系统上,IPv6 将优先,并且服务器可能不接受 IPv4 流量。客户端将尝试连接到名称解析返回的所有地址,并将流量发送到第一个成功连接的地址。
# Echo server program
import socket
import sys
HOST = None # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except OSError as msg:
s = None
continue
try:
s.bind(sa)
s.listen(1)
except OSError as msg:
s.close()
s = None
continue
break
if s is None:
print('could not open socket')
sys.exit(1)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data: break
conn.send(data)
# Echo client program
import socket
import sys
HOST = 'daring.cwi.nl' # The remote host
PORT = 50007 # The same port as used by the server
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except OSError as msg:
s = None
continue
try:
s.connect(sa)
except OSError as msg:
s.close()
s = None
continue
break
if s is None:
print('could not open socket')
sys.exit(1)
with s:
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', repr(data))
下一个示例演示如何在 Windows 上使用原始套接字编写一个非常简单的网络嗅探器。该示例需要管理员权限才能修改接口
import socket
# the public network interface
HOST = socket.gethostbyname(socket.gethostname())
# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))
# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# receive all packets
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
# receive a packet
print(s.recvfrom(65565))
# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
下一个示例演示如何使用套接字接口使用原始套接字协议与 CAN 网络进行通信。要改用广播管理器协议使用 CAN,请使用以下命令打开套接字
socket.socket(socket.AF_CAN, socket.SOCK_DGRAM, socket.CAN_BCM)
绑定 (CAN_RAW
) 或连接 (CAN_BCM
) 套接字后,您可以像往常一样在套接字对象上使用 socket.send()
和 socket.recv()
操作(及其对应操作)。
最后一个示例可能需要特殊权限
import socket
import struct
# CAN frame packing/unpacking (see 'struct can_frame' in <linux/can.h>)
can_frame_fmt = "=IB3x8s"
can_frame_size = struct.calcsize(can_frame_fmt)
def build_can_frame(can_id, data):
can_dlc = len(data)
data = data.ljust(8, b'\x00')
return struct.pack(can_frame_fmt, can_id, can_dlc, data)
def dissect_can_frame(frame):
can_id, can_dlc, data = struct.unpack(can_frame_fmt, frame)
return (can_id, can_dlc, data[:can_dlc])
# create a raw socket and bind it to the 'vcan0' interface
s = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
s.bind(('vcan0',))
while True:
cf, addr = s.recvfrom(can_frame_size)
print('Received: can_id=%x, can_dlc=%x, data=%s' % dissect_can_frame(cf))
try:
s.send(cf)
except OSError:
print('Error sending CAN frame')
try:
s.send(build_can_frame(0x01, b'\x01\x02\x03'))
except OSError:
print('Error sending CAN frame')
在两次执行之间延迟太短的情况下多次运行示例可能会导致此错误
OSError: [Errno 98] Address already in use
这是因为之前的执行使套接字处于 TIME_WAIT
状态,并且无法立即重用。
有一个 socket
标志可以设置,以防止这种情况发生,socket.SO_REUSEADDR
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
SO_REUSEADDR
标志告诉内核重用 TIME_WAIT
状态的本地套接字,而无需等待其自然超时到期。
另请参阅
有关套接字编程(使用 C 语言)的介绍,请参阅以下论文
An Introductory 4.3BSD Interprocess Communication Tutorial,作者 Stuart Sechrest
An Advanced 4.3BSD Interprocess Communication Tutorial,作者 Samuel J. Leffler 等人
这两篇论文都可以在 UNIX 程序员手册的补充文档 1 中找到(章节 PS1:7 和 PS1:8)。有关各种套接字相关系统调用的平台特定参考资料也是了解套接字语义详细信息的宝贵资源。对于 Unix,请参阅手册页;对于 Windows,请参阅 WinSock(或 Winsock 2)规范。对于支持 IPv6 的 API,读者可以参考 RFC 3493,标题为“IPv6 的基本套接字接口扩展”。