socket — 低级别网络接口

源代码: Lib/socket.py


此模块提供对 BSD socket 接口的访问。它在所有现代 Unix 系统、Windows、MacOS 以及可能更多的平台上都可用。

备注

由于调用的是操作系统套接字 API,某些行为可能与平台相关。

可用性:非 WASI。

此模块在 WebAssembly 上不起作用或不可用。有关更多信息,请参阅 WebAssembly 平台

Python 接口是 Unix 系统调用和套接字库接口到 Python 面向对象风格的直接转译:socket() 函数返回一个 套接字对象,其方法实现了各种套接字系统调用。参数类型比 C 接口更高级:与 Python 文件上的 read()write() 操作一样,接收操作中的缓冲区分配是自动的,发送操作中的缓冲区长度是隐式的。

参见

模块 socketserver

简化网络服务器编写的类。

模块 ssl

套接字对象的 TLS/SSL 封装。

套接字家族

根据系统和构建选项,此模块支持各种套接字家族。

特定套接字对象所需的地址格式会根据创建套接字对象时指定的地址家族自动选择。套接字地址表示如下:

  • 绑定到文件系统节点的 AF_UNIX 套接字的地址表示为字符串,使用文件系统编码和 'surrogateescape' 错误处理程序(参见 PEP 383)。Linux 抽象命名空间中的地址作为 bytes-like object 返回,带有一个初始的空字节;请注意,此命名空间中的套接字可以与普通文件系统套接字通信,因此旨在在 Linux 上运行的程序可能需要处理两种类型的地址。在作为参数传递时,字符串或 bytes-like object 可用于任一类型的地址。

    3.3 版本中的变化: 以前,AF_UNIX 套接字路径假定使用 UTF-8 编码。

    3.5 版本中修改: 现在接受可写 bytes-like object

  • 对于 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),其中 flowinfoscope_id 表示 C 语言中 struct sockaddr_in6sin6_flowinfosin6_scope_id 成员。对于 socket 模块方法,为了向后兼容,可以省略 flowinfoscope_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_typeTIPC_ADDR_NAMESEQTIPC_ADDR_NAMETIPC_ADDR_ID 之一。

    • scopeTIPC_ZONE_SCOPETIPC_CLUSTER_SCOPETIPC_NODE_SCOPE 之一。

    • 如果 addr_typeTIPC_ADDR_NAME,则 v1 是服务器类型,v2 是端口标识符,v3 应该为 0。

      如果 addr_typeTIPC_ADDR_NAMESEQ,则 v1 是服务器类型,v2 是低端口号,v3 是高端口号。

      如果 addr_typeTIPC_ADDR_ID,则 v1 是节点,v2 是引用,v3 应该设置为 0。

  • 对于 AF_CAN 地址家族,使用元组 (interface, ),其中 interface 是一个字符串,表示网络接口名称,例如 'can0'。网络接口名称 '' 可用于从该家族的所有网络接口接收数据包。

    • CAN_ISOTP 协议需要一个元组 (interface, rx_addr, tx_addr),其中两个附加参数都是表示 CAN 标识符(标准或扩展)的无符号长整数。

    • CAN_J1939 协议需要一个元组 (interface, name, pgn, addr),其中附加参数是一个表示 ECU 名称的 64 位无符号整数、一个表示参数组号 (PGN) 的 32 位无符号整数和一个表示地址的 8 位整数。

  • 对于 PF_SYSTEM 家族的 SYSPROTO_CONTROL 协议,使用字符串或元组 (id, unit)。字符串是使用动态分配 ID 的内核控制的名称。如果已知内核控制的 ID 和单元号,或者使用已注册的 ID,则可以使用该元组。

    在 3.3 版本加入。

  • AF_BLUETOOTH 支持以下协议和地址格式

    • BTPROTO_L2CAP 接受一个元组 (bdaddr, psm[, cid[, bdaddr_type]]),其中

      • bdaddr 是一个指定蓝牙地址的字符串。

      • psm 是一个指定协议/服务复用器的整数。

      • cid 是一个可选的整数,指定通道标识符。如果未给出,则默认为零。

      • bdaddr_type 是一个可选的整数,指定地址类型;可以是 BDADDR_BREDR(默认)、BDADDR_LE_PUBLICBDADDR_LE_RANDOM 之一。

      3.14 版本中的变化: 添加了 cidbdaddr_type 字段。

    • BTPROTO_RFCOMM 接受 (bdaddr, channel),其中 bdaddr 是作为字符串的蓝牙地址,channel 是一个整数。

    • BTPROTO_HCI 接受的格式取决于您的操作系统。

      • 在 Linux 上,它接受一个整数 device_id 或一个元组 (device_id, [channel]),其中 device_id 指定蓝牙设备的编号,channel 是一个可选的整数,指定 HCI 通道(默认为 HCI_CHANNEL_RAW)。

      • 在 FreeBSD、NetBSD 和 DragonFly BSD 上,它接受 bdaddr,其中 bdaddr 是作为字符串的蓝牙地址。

      3.2 版本中的变化: 添加了 NetBSD 和 DragonFlyBSD 支持。

      3.13.3 版本中的变化: 添加了 FreeBSD 支持。

      3.14 版本中的变化: 添加了 channel 字段。现在接受未打包在元组中的 device_id

    • BTPROTO_SCO 接受 bdaddr,其中 bdaddr 是作为字符串或 bytes 对象的蓝牙地址。(例如 '12:23:34:45:56:67'b'12:23:34:45:56:67'

      3.14 版本中的变化: 添加了 FreeBSD 支持。

  • AF_ALG 是一个仅限 Linux 的基于套接字的内核加密接口。算法套接字使用包含两到四个元素的元组 (type, name [, feat [, mask]]) 进行配置,其中

    • type 是算法类型字符串,例如 aeadhashskcipherrng

    • name 是算法名称和操作模式字符串,例如 sha256hmac(sha256)cbc(aes)drbg_nopr_ctr_aes256

    • featmask 是无符号 32 位整数。

    可用性: Linux >= 2.6.38。

    某些算法类型需要较新的内核。

    在 3.6 版本加入。

  • AF_VSOCK 允许虚拟机与其主机之间进行通信。套接字表示为 (CID, port) 元组,其中上下文 ID 或 CID 和端口是整数。

    可用性: Linux >= 3.9

    参见 vsock(7)

    在 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 - 可选的 bytes-like object,指定硬件物理地址,其解释取决于设备。

    可用性: Linux >= 2.2。

  • AF_QIPCRTR 是一个仅限 Linux 的基于套接字的接口,用于与高通平台协处理器上运行的服务进行通信。地址家族表示为 (node, port) 元组,其中 nodeport 是非负整数。

    可用性: 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_idservice_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 套接字地址的 host 部分中使用主机名,程序可能会表现出不确定性行为,因为 Python 使用 DNS 解析返回的第一个地址。套接字地址将根据 DNS 解析结果和/或主机配置解析为不同的实际 IPv4/v6 地址。为了确定性行为,请在 host 部分使用数字地址。

所有错误都会引发异常。可能会引发参数类型无效和内存不足的常见异常。与套接字或地址语义相关的错误会引发 OSError 或其子类之一。

通过 setblocking() 支持非阻塞模式。通过 settimeout() 支持基于超时的泛化。

模块内容

模块 socket 导出以下元素。

异常

exception socket.error

已弃用的 OSError 别名。

3.3 版本中的变化: 根据 PEP 3151,此类别被设置为 OSError 的别名。

exception socket.herror

OSError 的子类,此异常针对地址相关错误引发,即对于在 POSIX C API 中使用 h_errno 的函数,包括 gethostbyname_ex()gethostbyaddr()。伴随值是一个表示库调用返回错误的对 (h_errno, string)h_errno 是一个数值,而 string 表示 h_errno 的描述,由 hstrerror() C 函数返回。

3.3 版本中的变化: 此类别被设置为 OSError 的子类。

exception socket.gaierror

OSError 的子类,此异常由 getaddrinfo()getnameinfo() 针对地址相关错误引发。伴随值是一个表示库调用返回错误的对 (error, string)string 表示 error 的描述,由 gai_strerror() C 函数返回。数字 error 值将与此模块中定义的 EAI_* 常量之一匹配。

3.3 版本中的变化: 此类别被设置为 OSError 的子类。

exception socket.timeout

TimeoutError 的已弃用别名。

OSError 的子类,当套接字通过先前调用 settimeout()(或通过 setdefaulttimeout() 隐式)启用了超时并发生超时时,会引发此异常。伴随值是一个字符串,其值目前始终是“timed out”。

3.3 版本中的变化: 此类别被设置为 OSError 的子类。

3.10 版本中的变化: 此类别被设置为 TimeoutError 的别名。

常量

AF_* 和 SOCK_* 常量现在是 AddressFamilySocketKind 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_STREAMSOCK_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 协议文档中记录的许多这些形式的常量也在 socket 模块中定义。它们通常用作套接字对象的 setsockopt()getsockopt() 方法的参数。在大多数情况下,只定义了 Unix 头文件中定义的符号;对于少数符号,提供了默认值。

3.6 版本中的变化: 添加了 SO_DOMAINSO_PROTOCOLSO_PEERSECSO_PASSSECTCP_USER_TIMEOUTTCP_CONGESTION

3.6.5 版本中的变化: 在可用时,添加了对 Windows 平台上的 TCP_FASTOPENTCP_KEEPCNT 的支持。

3.7 版本中的变化: 添加了 TCP_NOTSENT_LOWAT

在可用时,添加了对 Windows 平台上的 TCP_KEEPIDLETCP_KEEPINTVL 的支持。

3.10 版本中的变化: 添加了 IP_RECVTOS。添加了 TCP_KEEPALIVE。在 MacOS 上,此常量可以像 Linux 上使用 TCP_KEEPIDLE 一样使用。

3.11 版本中的变化: 添加了 TCP_CONNECTION_INFO。在 MacOS 上,此常量可以像 Linux 和 BSD 上使用 TCP_INFO 一样使用。

3.12 版本中的变化: 添加了 SO_RTABLESO_USER_COOKIE。在 OpenBSD 和 FreeBSD 上,这些常量可以分别像 Linux 上使用 SO_MARK 一样使用。还添加了 Linux 缺少的 TCP 套接字选项:TCP_MD5SIGTCP_THIN_LINEAR_TIMEOUTSTCP_THIN_DUPACKTCP_REPAIRTCP_REPAIR_QUEUETCP_QUEUE_SEQTCP_REPAIR_OPTIONSTCP_TIMESTAMPTCP_CC_INFOTCP_SAVE_SYNTCP_SAVED_SYNTCP_REPAIR_WINDOWTCP_FASTOPEN_CONNECTTCP_ULPTCP_MD5SIG_EXTTCP_FASTOPEN_KEYTCP_FASTOPEN_NO_COOKIETCP_ZEROCOPY_RECEIVETCP_INQTCP_TX_DELAY。添加了 IP_PKTINFOIP_UNBLOCK_SOURCEIP_BLOCK_SOURCEIP_ADD_SOURCE_MEMBERSHIPIP_DROP_SOURCE_MEMBERSHIP

3.13 版本中的变化: 添加了 SO_BINDTOIFINDEX。在 Linux 上,此常量可以像使用 SO_BINDTODEVICE 一样使用,但使用网络接口的索引而不是其名称。

3.14 版本中的变化: 在 Linux 上恢复了缺少的 IP_FREEBINDIP_RECVERRIPV6_RECVERRIP_RECVTTLIP_RECVORIGDSTADDR

3.14 版本中的变化: 在可用时,添加了对 Windows 平台上的 TCP_QUICKACK 的支持。

socket.AF_CAN
socket.PF_CAN
SOL_CAN_*
CAN_*

许多这些形式的常量,在 Linux 文档中记载,也在 socket 模块中定义。

可用性: Linux >= 2.6.25, NetBSD >= 8。

在 3.3 版本加入。

3.11 版本中的变化: 添加了 NetBSD 支持。

3.14 版本中的变化: 恢复了 Linux 上缺少的 CAN_RAW_ERR_FILTER

socket.CAN_BCM
CAN_BCM_*

CAN_BCM,在 CAN 协议家族中,是广播管理器(BCM)协议。广播管理器常量,在 Linux 文档中记载,也在 socket 模块中定义。

可用性: 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 文档中记载,也在 socket 模块中定义。

可用性: 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 文档中记载,也在 socket 模块中定义。

可用性: 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_*

TIPC 相关常量,与 C 套接字 API 导出的常量匹配。有关更多信息,请参阅 TIPC 文档。

socket.AF_ALG
socket.SOL_ALG
ALG_*

Linux 内核加密的常量。

可用性: Linux >= 2.6.38。

在 3.6 版本加入。

socket.AF_VSOCK
socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID
VMADDR*
SO_VM*

Linux 主机/访客通信的常量。

可用性: Linux >= 4.8。

在 3.7 版本加入。

可用性: BSD, macOS。

在 3.4 版本加入。

socket.has_ipv6

此常量包含一个布尔值,表示此平台上是否支持 IPv6。

socket.AF_BLUETOOTH
socket.BTPROTO_L2CAP
socket.BTPROTO_RFCOMM
socket.BTPROTO_HCI
socket.BTPROTO_SCO

用于蓝牙地址的整数常量。

socket.BDADDR_ANY
socket.BDADDR_LOCAL

这些是包含特殊含义的蓝牙地址字符串常量。例如,BDADDR_ANY 可用于在使用 BTPROTO_RFCOMM 指定绑定套接字时指示任何地址。

socket.BDADDR_BREDR
socket.BDADDR_LE_PUBLIC
socket.BDADDR_LE_RANDOM

这些常量描述了绑定或连接 BTPROTO_L2CAP 套接字时的蓝牙地址类型。

可用性: Linux, FreeBSD

在 3.14 版本加入。

socket.SOL_RFCOMM
socket.SOL_L2CAP
socket.SOL_HCI
socket.SOL_SCO
socket.SOL_BLUETOOTH

用于蓝牙套接字对象的 setsockopt()getsockopt() 方法的 level 参数。

SOL_BLUETOOTH 仅在 Linux 上可用。如果支持相应的协议,则其他常量可用。

SO_L2CAP_*
socket.L2CAP_LM
L2CAP_LM_*
SO_RFCOMM_*
RFCOMM_LM_*
SO_SCO_*
SO_BTH_*
BT_*

用于蓝牙套接字对象的 setsockopt()getsockopt() 方法的 option name 和 value 参数。

BT_*L2CAP_LM 仅在 Linux 上可用。SO_BTH_* 仅在 Windows 上可用。其他常量可能在 Linux 和各种 BSD 平台上可用。

在 3.14 版本加入。

socket.HCI_FILTER
socket.HCI_TIME_STAMP
socket.HCI_DATA_DIR
socket.SO_HCI_EVT_FILTER
socket.SO_HCI_PKT_FILTER

用于 BTPROTO_HCI 的选项名称。选项值的可用性和格式取决于平台。

3.14 版本中的变化: 在 NetBSD 和 DragonFly BSD 上添加了 SO_HCI_EVT_FILTERSO_HCI_PKT_FILTER。在 FreeBSD、NetBSD 和 DragonFly BSD 上添加了 HCI_DATA_DIR

socket.HCI_DEV_NONE

用于创建不特定于单个蓝牙适配器的 HCI 套接字的 device_id 值。

可用性: Linux

在 3.14 版本加入。

socket.HCI_CHANNEL_RAW
socket.HCI_CHANNEL_USER
socket.HCI_CHANNEL_MONITOR
socket.HCI_CHANNEL_CONTROL
socket.HCI_CHANNEL_LOGGING

BTPROTO_HCI 地址中 channel 字段的可能值。

可用性: Linux

在 3.14 版本加入。

socket.AF_QIPCRTR

高通 IPC 路由器协议的常量,用于与提供远程处理器的服务通信。

可用性: Linux >= 4.7。

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.SO_INCOMING_CPU

用于优化 CPU 局部性的常量,与 SO_REUSEPORT 结合使用。

在 3.11 版本中新增。

可用性: Linux >= 3.9

socket.SO_REUSEPORT_LB

用于启用负载均衡的重复地址和端口绑定的常量。

在 3.14 版本加入。

可用性: FreeBSD >= 12.0

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 新版功能.

socket.ETHERTYPE_ARP
socket.ETHERTYPE_IP
socket.ETHERTYPE_IPV6
socket.ETHERTYPE_VLAN

IEEE 802.3 协议号。常量。

可用性:Linux, FreeBSD, macOS。

3.12 新版功能.

socket.SHUT_RD
socket.SHUT_WR
socket.SHUT_RDWR

这些常量被套接字对象的 shutdown() 方法使用。

可用性:非 WASI。

函数

创建套接字

以下函数都创建 套接字对象

class socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)

使用给定的地址族、套接字类型和协议号创建一个新套接字。地址族应为 AF_INET (默认值)、AF_INET6AF_UNIXAF_CANAF_PACKETAF_RDS。套接字类型应为 SOCK_STREAM (默认值)、SOCK_DGRAMSOCK_RAW 或可能是其他 SOCK_ 常量之一。协议号通常为零,可以省略;如果地址族是 AF_CAN,则协议应为 CAN_RAWCAN_BCMCAN_ISOTPCAN_J1939 之一。

如果指定了 *fileno*,则 *family*、*type* 和 *proto* 的值将从指定的文件描述符自动检测。可以通过使用显式 *family*、*type* 或 *proto* 参数调用函数来覆盖自动检测。这只会影响 Python 如何表示例如 socket.getpeername() 的返回值,而不是实际的操作系统资源。与 socket.fromfd() 不同,*fileno* 将返回相同的套接字而不是副本。这可能有助于使用 socket.close() 关闭一个分离的套接字。

新创建的套接字是不可继承的

使用参数 selffamilytypeprotocol 触发 审计事件 socket.__new__

3.3 版更改: 添加了 AF_CAN 族。添加了 AF_RDS 族。

3.4 版更改: 添加了 CAN_BCM 协议。

3.4 版更改: 返回的套接字现在是不可继承的。

3.7 版更改: 添加了 CAN_ISOTP 协议。

3.7 版更改: SOCK_NONBLOCKSOCK_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_UNIX;否则,默认族为 AF_INET

新创建的套接字是不可继承的

3.2 版更改: 返回的套接字对象现在支持完整的套接字 API,而不仅仅是子集。

3.4 版更改: 返回的套接字现在是不可继承的。

3.5 版更改: 增加了对 Windows 的支持。

socket.create_connection(address, timeout=GLOBAL_DEFAULT, source_address=None, *, all_errors=False)

连接到侦听在互联网 *address*(一个 2 元组 (host, port))的 TCP 服务,并返回套接字对象。这是一个比 socket.connect() 更高级的函数:如果 *host* 是非数字主机名,它将尝试为 AF_INETAF_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_INETAF_INET6。*backlog* 是传递给 socket.listen() 的队列大小;如果未指定,将选择一个合理的默认值。*reuse_port* 决定是否设置 SO_REUSEPORT 套接字选项。

如果 *dualstack_ipv6* 为真,*family* 为 AF_INET6 并且平台支持它,则套接字将能够接受 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.fromshare(data)

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=AF_UNSPEC, type=0, proto=0, flags=0)

此函数封装了底层系统的 C 函数 getaddrinfo

将 *host*/*port* 参数转换为包含创建连接到该服务所需的所有参数的 5 元组序列。*host* 是一个域名、IPv4/v6 地址的字符串表示或 None。*port* 是一个字符串服务名,例如 'http'、一个数字端口号或 None。通过将 *host* 和 *port* 的值设置为 None,可以将 NULL 传递给底层 C API。

可以可选地指定 *family*、*type* 和 *proto* 参数,以提供选项并限制返回的地址列表。传入它们的默认值(分别为 AF_UNSPEC、0 和 0)以不限制结果。有关详细信息,请参阅下面的注释。

*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() 方法。

备注

如果你打算使用 getaddrinfo() 的结果来创建套接字(而不是,例如,检索 *canonname*),请考虑通过 *type*(例如 SOCK_STREAMSOCK_DGRAM)和/或 *proto*(例如 IPPROTO_TCPIPPROTO_UDP)来限制结果,以使你的应用程序能够处理。

*family*、*type*、*proto* 和 *flags* 的默认值的行为因系统而异。

许多系统(例如,大多数 Linux 配置)将返回所有匹配地址的排序列表。这些地址通常应按顺序尝试,直到连接成功(可能并行尝试,例如,使用 Happy Eyeballs 算法)。在这些情况下,限制 *type* 和/或 *proto* 可以帮助消除不成功或无法使用的连接尝试。

然而,某些系统只会返回单个地址。(例如,这在 Solaris 和 AIX 配置上有所报道。)在这些系统上,限制 *type* 和/或 *proto* 有助于确保此地址可用。

使用参数 hostportfamilytypeprotocol 触发 审计事件 socket.getaddrinfo

以下示例获取了到 example.org 端口 80 的假定 TCP 连接的地址信息(如果未启用 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 名称解析,对于 IPv4/v6 双栈支持,应改用 getaddrinfo()

使用参数 hostname 触发 审计事件 socket.gethostbyname

可用性:非 WASI。

socket.gethostbyname_ex(hostname)

将主机名转换为 IPv4 地址格式,扩展接口。返回一个 3 元组 (hostname, aliaslist, ipaddrlist),其中 *hostname* 是主机的主要主机名,*aliaslist* 是同一地址的替代主机名列表(可能为空),*ipaddrlist* 是同一主机上同一接口的 IPv4 地址列表(通常但并非总是单个地址)。gethostbyname_ex() 不支持 IPv6 名称解析,对于 IPv4/v6 双栈支持,应改用 getaddrinfo()

使用参数 hostname 触发 审计事件 socket.gethostbyname

可用性:非 WASI。

socket.gethostname()

返回一个包含 Python 解释器当前正在执行的机器的主机名的字符串。

不带任何参数触发 审计事件 socket.gethostname

注意:gethostname() 不总是返回完全限定域名;请使用 getfqdn()

可用性:非 WASI。

socket.gethostbyaddr(ip_address)

返回一个 3 元组 (hostname, aliaslist, ipaddrlist),其中 *hostname* 是响应给定 *ip_address* 的主要主机名,*aliaslist* 是同一地址的替代主机名列表(可能为空),*ipaddrlist* 是同一主机上同一接口的 IPv4/v6 地址列表(很可能只包含一个地址)。要查找完全限定域名,请使用函数 getfqdn()gethostbyaddr() 支持 IPv4 和 IPv6。

使用参数 ip_address 触发 审计事件 socket.gethostbyaddr

可用性:非 WASI。

socket.getnameinfo(sockaddr, flags)

将套接字地址 *sockaddr* 转换为 2 元组 (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。请注意,具体什么是有效取决于底层 C 实现的 inet_aton()

inet_aton() 不支持 IPv6,对于 IPv4/v6 双栈支持,应改用 inet_pton()

socket.inet_ntoa(packed_ip)

将 32 位打包的 IPv4 地址(一个长度为四字节的类字节对象)转换为其标准点分四段字符串表示(例如,'123.45.67.89')。这在与使用标准 C 库并需要 in_addr 类型对象的程序通信时很有用,in_addr 是此函数作为参数的 32 位打包二进制数据的 C 类型。

如果传递给此函数的字节序列长度不正好是 4 字节,将引发 OSErrorinet_ntoa() 不支持 IPv6,对于 IPv4/v6 双栈支持,应改用 inet_ntop()

3.5 版本中修改: 现在接受可写 bytes-like object

socket.inet_pton(address_family, ip_string)

将 IP 地址从其家族特定的字符串格式转换为打包的二进制格式。inet_pton() 在库或网络协议要求 in_addr 类型对象(类似于 inet_aton())或 in6_addr 时很有用。

目前支持的 *address_family* 值为 AF_INETAF_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_INETAF_INET6。如果字节对象 *packed_ip* 的长度与指定地址族不符,将引发 ValueErrorinet_ntop() 调用出错时将引发 OSError

可用性: Unix, Windows。

3.4 版更改: 添加了 Windows 支持

3.5 版本中修改: 现在接受可写 bytes-like object

socket.CMSG_LEN(length)

返回一个具有给定 *length* 关联数据的辅助数据项的总长度(不含尾部填充)。这个值通常可用作 recvmsg() 的缓冲区大小,以接收单个辅助数据项,但 RFC 3542 要求可移植应用程序使用 CMSG_SPACE() 并因此包含填充空间,即使该项将是缓冲区中的最后一项。如果 *length* 超出允许的值范围,则引发 OverflowError

可用性: Unix,不包括 WASI。

大多数 Unix 平台。

在 3.3 版本加入。

socket.CMSG_SPACE(length)

返回 recvmsg() 接收具有给定 *length* 关联数据以及任何尾部填充的辅助数据项所需的缓冲区大小。接收多个项所需的缓冲区空间是其关联数据长度的 CMSG_SPACE() 值之和。如果 *length* 超出允许的值范围,则引发 OverflowError

请注意,有些系统可能支持辅助数据但未提供此函数。另请注意,使用此函数的结果设置缓冲区大小可能无法精确限制可接收的辅助数据量,因为额外的​​数据可能能够容纳到填充区域中。

可用性: Unix,不包括 WASI。

大多数 Unix 平台。

在 3.3 版本加入。

socket.getdefaulttimeout()

返回新套接字对象的默认超时时间(浮点数,单位秒)。值为 None 表示新套接字对象没有超时。当首次导入套接字模块时,默认值为 None

socket.setdefaulttimeout(timeout)

设置新套接字对象的默认超时时间(浮点数,单位秒)。当套接字模块首次导入时,默认值为 None。有关可能的值及其各自含义,请参阅 settimeout()

socket.sethostname(name)

将机器的主机名设置为 *name*。如果您没有足够的权限,这将引发 OSError

使用参数 name 触发 审计事件 socket.sethostname

可用性:Unix,非 Android。

在 3.3 版本加入。

socket.if_nameindex()

返回网络接口信息 (索引整数,名称字符串) 元组列表。OSError 如果系统调用失败。

可用性:Unix, Windows, 非 WASI。

在 3.3 版本加入。

3.8 版更改: 添加了 Windows 支持。

备注

在 Windows 上,网络接口在不同的上下文中具有不同的名称(所有名称均为示例)

  • UUID: {FB605B73-AAC2-49A6-9A2F-25416AEA0573}

  • 名称: ethernet_32770

  • 友好名称: vEthernet (nat)

  • 描述: Hyper-V Virtual Ethernet Adapter

此函数返回列表中第二种形式的名称,在此示例中为 ethernet_32770

socket.if_nametoindex(if_name)

返回与接口名称对应的网络接口索引号。如果不存在具有给定名称的接口,则引发 OSError

可用性:Unix, Windows, 非 WASI。

在 3.3 版本加入。

3.8 版更改: 添加了 Windows 支持。

参见

“接口名称”是 if_nameindex() 中记录的名称。

socket.if_indextoname(if_index)

返回与接口索引号对应的网络接口名称。如果不存在具有给定索引的接口,则引发 OSError

可用性:Unix, Windows, 非 WASI。

在 3.3 版本加入。

3.8 版更改: 添加了 Windows 支持。

参见

“接口名称”是 if_nameindex() 中记录的名称。

socket.send_fds(sock, buffers, fds[, flags[, address]])

通过 AF_UNIX 套接字 *sock* 发送文件描述符列表 *fds*。*fds* 参数是一个文件描述符序列。有关这些参数的文档,请参阅 sendmsg()

可用性: Unix,不包括 WASI。

支持 sendmsg()SCM_RIGHTS 机制的 Unix 平台。

在 3.9 版本中新增。

socket.recv_fds(sock, bufsize, maxfds[, flags])

AF_UNIX 套接字 *sock* 接收最多 *maxfds* 个文件描述符。返回 (msg, list(fds), flags, addr)。有关这些参数的文档,请参阅 recvmsg()

可用性: Unix,不包括 WASI。

支持 recvmsg()SCM_RIGHTS 机制的 Unix 平台。

在 3.9 版本中新增。

备注

文件描述符列表末尾的任何截断整数。

套接字对象

套接字对象具有以下方法。除了 makefile(),这些都对应于适用于套接字的 Unix 系统调用。

3.2 版更改: 增加了对上下文管理器协议的支持。退出上下文管理器等同于调用 close()

socket.accept()

接受连接。套接字必须绑定到地址并侦听连接。返回值是一对 (conn, address),其中 *conn* 是一个 *新的* 套接字对象,可用于在连接上发送和接收数据,*address* 是绑定到连接另一端的套接字地址。

新创建的套接字是不可继承的

3.4 版更改: 套接字现在是不可继承的。

3.5 版更改: 如果系统调用被中断并且信号处理程序没有引发异常,该方法现在会重试系统调用,而不是引发 InterruptedError 异常(有关原因请参阅 PEP 475)。

socket.bind(address)

将套接字绑定到 *address*。套接字不得已绑定。(*address* 的格式取决于地址族 —— 请参见上文。)

使用参数 selfaddress 触发 审计事件 socket.bind

可用性:非 WASI。

socket.close()

将套接字标记为已关闭。当所有来自 makefile() 的文件对象都关闭时,底层系统资源(例如文件描述符)也会关闭。一旦发生这种情况,所有对套接字对象的未来操作都将失败。远程端将不再接收数据(在排队数据刷新之后)。

套接字在垃圾回收时会自动关闭,但建议显式 close() 它们,或者在它们周围使用 with 语句。

3.6 版更改: 当底层 close() 调用发生错误时,现在会引发 OSError

备注

close() 释放与连接关联的资源,但不一定会立即关闭连接。如果您想及时关闭连接,请在 close() 之前调用 shutdown()

socket.connect(address)

连接到 *address* 处的远程套接字。(*address* 的格式取决于地址族 —— 请参见上文。)

如果连接被信号中断,该方法将等待直到连接完成,或者在超时时引发 TimeoutError(如果信号处理程序没有引发异常且套接字是阻塞的或有超时)。对于非阻塞套接字,如果连接被信号中断(或信号处理程序引发的异常),该方法将引发 InterruptedError 异常。

使用参数 selfaddress 触发 审计事件 socket.connect

3.5 版更改: 如果连接被信号中断,信号处理程序不引发异常且套接字是阻塞的或有超时,该方法现在会等待连接完成,而不是引发 InterruptedError 异常(有关原因请参阅 PEP 475)。

可用性:非 WASI。

socket.connect_ex(address)

类似于 connect(address),但对于 C 级 connect() 调用返回的错误,返回错误指示器而不是引发异常(其他问题,例如“找不到主机”,仍可能引发异常)。如果操作成功,错误指示器为 0,否则为 errno 变量的值。这对于支持异步连接等情况很有用。

使用参数 selfaddress 触发 审计事件 socket.connect

可用性:非 WASI。

socket.detach()

将套接字对象置于关闭状态,而不实际关闭底层文件描述符。文件描述符被返回,可用于其他目的。

在 3.2 版本加入。

socket.dup()

复制套接字。

新创建的套接字是不可继承的

3.4 版更改: 套接字现在是不可继承的。

可用性:非 WASI。

socket.fileno()

返回套接字的文件描述符(一个小的整数),失败时返回 -1。这在与 select.select() 结合使用时很有用。

在 Windows 下,此方法返回的小整数不能用于文件描述符可用的地方(例如 os.fdopen())。Unix 没有此限制。

socket.get_inheritable()

获取套接字的文件描述符或套接字句柄的 可继承标志:如果套接字可以在子进程中继承,则为 True;否则为 False

在 3.4 版本加入。

socket.getpeername()

返回套接字连接到的远程地址。这对于查找远程 IPv4/v6 套接字的端口号非常有用。(返回地址的格式取决于地址族 — 参见上文。)在某些系统上不支持此函数。

socket.getpeername()

返回套接字本身的地址。这对于查找 IPv4/v6 套接字的端口号非常有用。(返回地址的格式取决于地址族 — 参见上文。)

socket.getsockopt(level, optname[, buflen])

返回给定套接字选项的值(参见 Unix 手册页 getsockopt(2))。所需的符号常量(SO_* 等。)在此模块中定义。如果 buflen 不存在,则假定为整数选项,并由函数返回其整数值。如果 buflen 存在,它指定用于接收选项的缓冲区的最大长度,并且此缓冲区作为 bytes 对象返回。调用者负责解码缓冲区的内容(请参见可选的内置模块 struct,了解如何解码编码为字节串的 C 结构)。

可用性:非 WASI。

socket.getblocking()

如果套接字处于阻塞模式,则返回 True;如果处于非阻塞模式,则返回 False

这相当于检查 socket.gettimeout() != 0

在 3.7 版本加入。

socket.gettimeout()

返回与套接字操作关联的超时时间(浮点数,单位为秒),如果未设置超时,则返回 None。这反映了上次调用 setblocking()settimeout() 的结果。

socket.ioctl(control, option)

ioctl() 方法是 WSAIoctl 系统接口的有限接口。有关更多信息,请参阅 Win32 文档

在其他平台上,可以使用通用的 fcntl.fcntl()fcntl.ioctl() 函数;它们接受一个套接字对象作为它们的第一个参数。

目前仅支持以下控制代码:SIO_RCVALLSIO_KEEPALIVE_VALSSIO_LOOPBACK_FAST_PATH

可用性: Windows

3.6 版本中的变化: 添加了 SIO_LOOPBACK_FAST_PATH

socket.listen([backlog])

使服务器能够接受连接。如果指定了 backlog,它必须至少为 0(如果低于 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);它默认为零。

版本 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_levelcmsg_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)。ancbufsizeflags 参数的含义与 recvmsg() 相同。

返回值是一个 4 元组:(nbytes, ancdata, msg_flags, address),其中 nbytes 是写入缓冲区的非辅助数据的总字节数,而 ancdatamsg_flagsaddressrecvmsg() 相同。

示例

>>> 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 的格式取决于地址族 — 参见上文。)

使用参数 selfaddress 触发一个 审计事件 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_levelcmsg_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 平台。

使用参数 selfaddress 触发一个 审计事件 socket.sendmsg

在 3.3 版本加入。

版本 3.5 中有所改变: 如果系统调用被中断且信号处理程序未引发异常,则该方法现在会重试系统调用,而不是引发 InterruptedError 异常(参见 PEP 475 以了解其原理)。

socket.sendmsg_afalg([msg, ]*, op[, iv[, assoclen[, flags]]])

sendmsg() 的专用版本,用于 AF_ALG 套接字。为 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.set_inheritable(inheritable)

设置套接字的文件描述符或套接字句柄的 可继承标志

在 3.4 版本加入。

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: int)
socket.setsockopt(level, optname, value: buffer)
socket.setsockopt(level, optname, None, optlen: int)

设置给定套接字选项的值(参见 Unix 手册页 setsockopt(2))。所需的符号常量在此模块中定义(SO_* 等。 <socket-unix-constants>)。该值可以是一个整数、None 或一个表示缓冲区的类字节对象。在后一种情况下,调用者负责确保字节字符串包含正确的位(参见可选的内置模块 struct,了解如何将 C 结构编码为字节字符串)。当 value 设置为 None 时,需要 optlen 参数。这等同于调用 C 函数 setsockopt(),其中 optval=NULLoptlen=optlen

3.5 版本中修改: 现在接受可写 bytes-like object

版本 3.6 中有所改变: 添加了 setsockopt(level, optname, None, optlen: int) 形式。

可用性:非 WASI。

socket.shutdown(how)

关闭连接的一个或两个半部。如果 howSHUT_RD,则禁止进一步接收。如果 howSHUT_WR,则禁止进一步发送。如果 howSHUT_RDWR,则禁止进一步发送和接收。

可用性:非 WASI。

socket.share(process_id)

复制套接字并准备好与目标进程共享。目标进程必须通过 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() 方法返回的套接字将继承该超时。否则,行为取决于监听套接字的设置:

  • 如果监听套接字处于 阻塞模式超时模式,则由 accept() 返回的套接字处于 阻塞模式

  • 如果监听套接字处于 非阻塞模式,则由 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 Programmer's Manual, Supplementary Documents 1 (第 PS1:7 和 PS1:8 节) 中。各种套接字相关系统调用的平台特定参考资料也是了解套接字语义细节的宝贵信息来源。对于 Unix,请参阅手册页;对于 Windows,请参阅 WinSock(或 Winsock 2)规范。对于支持 IPv6 的 API,读者可能希望参考标题为 Basic Socket Interface Extensions for IPv6 的 RFC 3493