socket — 底层网络接口

源代码: Lib/socket.py


此模块提供对 BSD 套接字接口的访问。它在所有现代 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 上运行的程序可能需要处理这两种类型的地址。当将其作为参数传递时,字符串或类似字节的对象可用于任何类型的地址。

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

    在 3.5 版本中变更: 现在接受可写的 类字节对象

  • 对于 AF_INET 地址族,使用一对 (host, port),其中 *host* 是一个字符串,表示 internet 域表示法(如 '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_flowinfosin6_scope_id 成员。对于 socket 模块方法,为了向后兼容,可以省略 *flowinfo* 和 *scope_id*。但是,请注意,省略 *scope_id* 可能会导致在操作作用域 IPv6 地址时出现问题。

    在 3.7 版本中变更: 对于多播地址(*scope_id* 有意义),*address* 可能不包含 %scope_id (或 zone id)部分。此信息是多余的,可以安全地省略(建议)。

  • AF_NETLINK 套接字表示为 (pid, groups) 对。

  • 仅限 Linux 的对 TIPC 的支持使用 AF_TIPC 地址族。TIPC 是一种开放的、基于非 IP 的网络协议,旨在用于集群计算机环境中。地址由一个元组表示,字段取决于地址类型。通用元组形式为 (addr_type, v1, v2, v3 [, scope]),其中

    • *addr_type* 是 TIPC_ADDR_NAMESEQTIPC_ADDR_NAMETIPC_ADDR_ID 之一。

    • *scope* 是 TIPC_ZONE_SCOPETIPC_CLUSTER_SCOPETIPC_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。

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

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

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

  • 字符串或元组 (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 的基于套接字的内核密码接口。算法套接字配置有两到四个元素的元组 (类型, 名称 [, 特征 [, 掩码]]),其中

    • 类型 是作为字符串的算法类型,例如 aeadhashskcipherrng

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

    • 特征掩码 是无符号 32 位整数。

    可用性:Linux >= 2.6.38。

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

    3.6 版本新增。

  • AF_VSOCK 允许虚拟机及其主机之间进行通信。套接字表示为 (CID, 端口) 元组,其中上下文 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 - 可选的类似字节的对象,指定硬件物理地址,其解释取决于设备。

    可用性:Linux >= 2.2。

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

    可用性: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) 中。

    这样的套接字应该使用 IPv4 的 socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE) 或 IPv6 的 socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE) 构建。

    可用性: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* 的描述,由 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_* 常量现在是 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_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_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 以相同的方式使用,但使用的是网络接口的索引,而不是其名称。

socket.AF_CAN
socket.PF_CAN
SOL_CAN_*
CAN_*

Linux 文档中记录的许多此类形式的常量,也在 socket 模块中定义。

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

3.3 版本新增。

在 3.11 版本中更改: 添加了 NetBSD 支持。

socket.CAN_BCM
CAN_BCM_*

CAN 协议族中的 CAN_BCM 是广播管理器(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 协议族中的 CAN_ISOTP 是 ISO-TP (ISO 15765-2) 协议。Linux 文档中记录的 ISO-TP 常量。

可用性: Linux >= 2.6.25。

3.7 版本新增。

socket.CAN_J1939

CAN 协议族中的 CAN_J1939 是 SAE J1939 协议。Linux 文档中记录的 J1939 常量。

可用性: 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.BDADDR_ANY
socket.BDADDR_LOCAL

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

socket.HCI_FILTER
socket.HCI_TIME_STAMP
socket.HCI_DATA_DIR

用于 BTPROTO_HCIHCI_FILTER 不适用于 NetBSD 或 DragonFlyBSD。HCI_TIME_STAMPHCI_DATA_DIR 不适用于 FreeBSD、NetBSD 或 DragonFlyBSD。

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.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,则 familytypeproto 的值将从指定的文件描述符自动检测。可以通过使用显式的 familytypeproto 参数调用函数来覆盖自动检测。这只会影响 Python 如何表示,例如 socket.getpeername() 的返回值,而不会影响实际的操作系统资源。与 socket.fromfd() 不同,fileno 将返回相同的套接字,而不是重复的套接字。这有助于使用 socket.close() 关闭分离的套接字。

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

引发一个 审计事件 socket.__new__,参数为 selffamilytypeprotocol

在 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_INET

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

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

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

在 3.5 版本中更改: 添加了 Windows 支持。

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

连接到在 internet address(一个 2 元组 (host, port))上侦听的 TCP 服务,并返回套接字对象。这是一个比 socket.connect() 更高级别的函数:如果 host 是一个非数字主机名,它将尝试为 AF_INETAF_INET6 解析它,然后依次尝试连接到所有可能的地址,直到连接成功。这使得编写与 IPv4 和 IPv6 兼容的客户端变得容易。

传递可选的 timeout 参数将在尝试连接之前在套接字实例上设置超时。如果没有提供 timeout,则使用 getdefaulttimeout() 返回的全局默认超时设置。

如果提供,source_address 必须是一个 2 元组 (host, port),以便套接字在连接之前绑定到它作为源地址。如果 host 或 port 分别是 '' 或 0,则将使用操作系统默认行为。

当无法创建连接时,会引发异常。默认情况下,它是列表中最后一个地址的异常。如果 all_errorsTrue,则它是一个 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_INET6backlog 是传递给 socket.listen() 的队列大小;如果未指定,则选择默认的合理值。reuse_port 指示是否设置 SO_REUSEPORT 套接字选项。

如果 dualstack_ipv6 为 true 并且平台支持它,则该套接字将能够接受 IPv4 和 IPv6 连接,否则将引发 ValueError。大多数 POSIX 平台和 Windows 都应该支持此功能。启用此功能后,当发生 IPv4 连接时,socket.getpeername() 返回的地址将是表示为 IPv4 映射的 IPv6 地址的 IPv6 地址。如果 dualstack_ipv6 为 false,它将在默认启用此功能的平台(例如 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 地址的字符串表示形式或 Noneport 是一个字符串服务名称,例如 'http'、一个数字端口号或 None。通过将 None 作为 hostport 的值传递,可以将 NULL 传递给底层 C API。

可以有选择地指定 familytypeproto 参数,以便提供选项并限制返回的地址列表。传递它们的默认值(分别为 AF_UNSPEC、0 和 0)来不限制结果。请参阅下面的注释以了解详细信息。

flags 参数可以是 AI_* 常量中的一个或多个,并且会影响结果的计算和返回方式。例如,AI_NUMERICHOST 将禁用域名解析,并且如果 host 是域名,则会引发错误。

该函数返回一个包含以下结构的 5 元组列表

(family, type, proto, canonname, sockaddr)

在这些元组中,familytypeproto 都是整数,旨在传递给 socket() 函数。如果 AI_CANONNAMEflags 参数的一部分,则 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)来限制结果,您的应用程序可以处理。

familytypeprotoflags 的默认值的行为是特定于系统的。

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

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

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

以下示例为端口 80 上的 example.org 的假设 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 名称解析,应使用 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)

返回一个 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',否则将匹配任何协议。

引发带有参数 servicenameprotocolname审计事件 socket.getservbyname

可用性: 不适用于 WASI。

socket.getservbyport(port[, protocolname])

将互联网端口号和协议名称转换为该服务的服务名称。可选的协议名称(如果提供)应为 'tcp''udp',否则将匹配任何协议。

引发带有参数 portprotocolname审计事件 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)

将点分十进制字符串格式(例如,‘123.45.67.89’)的 IPv4 地址转换为 32 位打包二进制格式,以长度为四个字符的字节对象表示。当与使用标准 C 库且需要 in_addr 类型对象(即此函数返回的 32 位打包二进制的 C 类型)的程序交互时,此操作非常有用。

inet_aton() 也接受少于三个点的字符串;详情请参阅 Unix 手册页 inet(3)

如果传递给此函数的 IPv4 地址字符串无效,则会引发 OSError。请注意,具体什么被认为是有效取决于底层 C 实现的 inet_aton()

inet_aton() 不支持 IPv6,应使用 inet_pton() 来支持 IPv4/v6 双栈。

socket.inet_ntoa(packed_ip)

将 32 位打包的 IPv4 地址(长度为四个字节的 类字节对象)转换为其标准的点分十进制字符串表示形式(例如,‘123.45.67.89’)。当与使用标准 C 库且需要 in_addr 类型对象(即此函数接收的 32 位打包二进制数据的 C 类型)的程序交互时,此操作非常有用。

如果传递给此函数的字节序列的长度不是正好 4 个字节,则会引发 OSErrorinet_ntoa() 不支持 IPv6,应使用 inet_ntop() 来支持 IPv4/v6 双栈。

在 3.5 版本中变更: 现在接受可写的 类字节对象

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* 对于指定的地址族而言长度不正确,则会引发 ValueError。对于调用 inet_ntop() 产生的错误,会引发 OSError

可用性:Unix,Windows。

在 3.4 版本中更改: 添加了 Windows 支持

在 3.5 版本中变更: 现在接受可写的 类字节对象

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 值表示新套接字对象没有超时。首次导入 socket 模块时,默认值为 None

socket.setdefaulttimeout(timeout)

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

socket.sethostname(name)

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

引发一个 审计事件 socket.sethostname,参数为 name

可用性: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 发送文件描述符列表 fdsfds 参数是文件描述符的序列。有关这些参数的文档,请参阅sendmsg()

可用性:Unix、Windows,非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、Windows,非WASI。

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

引发一个 审计事件 socket.bind,参数为 selfaddress

可用性: 不适用于 WASI。

socket.close()

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

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

在 3.6 版本中变更: 如果在调用底层 close() 时发生错误,则现在会引发 OSError

注解

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

socket.connect(address)

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

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

引发一个 审计事件 socket.connect,其参数为 selfaddress

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

可用性: 不适用于 WASI。

socket.connect_ex(address)

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

引发一个 审计事件 socket.connect,其参数为 selfaddress

可用性: 不适用于 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.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_RCVALLSIO_KEEPALIVE_VALSSIO_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_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() 相同。返回发送的字节数。应用程序负责检查是否已发送所有数据;如果仅传输了部分数据,则应用程序需要尝试传递剩余数据。有关此主题的更多信息,请查阅 套接字编程 HOWTO

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

引发一个 审计事件 socket.sendto,其参数为 selfaddress

在 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]]])

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.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 或表示缓冲区的类字节对象。在后一种情况下,由调用方确保字节串包含正确的位(有关将 C 结构编码为字节串的方法,请参阅可选的内置模块 struct)。当 value 设置为 None 时,需要 optlen 参数。它等效于使用 optval=NULLoptlen=optlen 调用 setsockopt() C 函数。

在 3.5 版本中变更: 现在接受可写的 类字节对象

在 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 语言)的介绍,请参阅以下论文

  • 4.3BSD 进程间通信入门教程》,作者:Stuart Sechrest

  • 4.3BSD 高级进程间通信教程》,作者:Samuel J. Leffler 等

这两篇论文都收录于 UNIX 程序员手册,补充文档 1(PS1:7 和 PS1:8 部分)。各种与套接字相关的系统调用的特定于平台的参考资料也是了解套接字语义细节的重要来源。对于 Unix,请参考手册页;对于 Windows,请参阅 WinSock(或 Winsock 2)规范。对于支持 IPv6 的 API,读者可能需要参考 RFC 3493,标题为《IPv6 的基本套接字接口扩展》。