# 18.1. `socket` — 底层网络接口

源代码: Lib/socket.py

这个模块提供了访问BSD*套接字*的接口。在所有现代Unix系统、Windows、macOS和其他一些平台上可用。

備註

一些行为可能因平台不同而异，因为调用的是操作系统的套接字API。

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

也參考

模块 `socketserver`

  用于简化网络服务端编写的类。

模块 `ssl`

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

## 18.1.1. 套接字协议族

根据系统以及构建选项，此模块提供了各种 socket 协议簇。

特定的 socket 对象需要的地址格式将根据此 socket 对象被创建时指定的地址族被自动选择。socket 地址表示如下：

- 一个绑定在文件系统节点上的 `AF_UNIX` 套接字的地址表示为一个字符串，使用文件系统字符编码和 `'surrogateescape'` 错误回调方法（see PEP 383）。一个地址在 Linux 的抽象命名空间被返回为带有初始的 null 字节的 bytes-like object ；注意在这个命名空间种的套接字可能与普通文件系统套接字通信，所以打算运行在 Linux 上的程序可能需要解决两种地址类型。当传递为参数时，一个字符串或字节类对象可以用于任一类型的地址。

  > 3.3 版更變: 以前，`AF_UNIX` 套接字路径被假设使用 UTF-8 编码。

  > 3.5 版更變: 现在支持可写的 字节类对象。

- 一对 `(host, port)` 被用于 `AF_INET` 地址族，host 是一个代表互联网域名表示法之内主机名或者一个 IPv4 地址的字符串，例如 `'daring.cwi.nl'` 或 `'100.50.200.5'`，port 是一个整数。

  - 对于 IPv4 地址，有两种可接受的特殊形式被用来代替一个主机地址： `''` 代表 `INADDR_ANY`，用来绑定到所有接口；字符串 `'<broadcast>'` 代表 `INADDR_BROADCAST`。此行为不兼容 IPv6，因此，如果你的 Python 程序打算支持 IPv6，则可能需要避开这些。

- 对于 `AF_INET6` 地址族，使用一个四元组 `(host, port, flowinfo, scopeid)`， flowinfo 和 scopeid 代表了 C 库里 `struct sockaddr_in6` 中的 `sin6_flowinfo` 和 `sin6_scope_id` 成员。 对于 `socket` 模块中的方法， flowinfo 和 scopeid 可以被省略，只为了向后兼容。注意，scopeid 的省略可能会导致 IPv6 地址的操作范围问题。

- `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 是节点 (node)，v2 是 ref，v3 应为 0。

- `AF_CAN` 地址族使用元组 `(interface, )`，其中 interface 是表示网络接口名称的字符串，如 `'can0'`。网络接口名 `''` 可以用于接收本族所有网络接口的数据包。

- `PF_SYSTEM` 协议簇的 `SYSPROTO_CONTROL` 协议接受一个字符串或元组 `(id, unit)`。其中字符串是内核控件的名称，该控件使用动态分配的 ID。而如果 ID 和内核控件的单元 (unit) 编号都已知，或使用了已注册的 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 可用的、基于套接字的接口，用于连接内核加密算法。算法套接字可用包括 2 至 4 个元素的元组来配置 `(type, name [, feat [, mask]])`，其中：

  - type 是表示算法类型的字符串，如 `aead`、`hash`、`skcipher` 或 `rng`。

  - name 是表示算法类型和操作模式的字符串，如 `sha256`、`hmac(sha256)`、`cbc(aes)` 或 `drbg_nopr_ctr_aes256`。

  - feat 和 mask 是无符号 32 位整数。

  Availability Linux 2.6.38, some algorithm types require more recent Kernels.

  3.6 版新加入.

- `AF_PACKET` 是一个底层接口，直接连接至网卡。数据包使用元组 `(ifname, proto[, pkttype[, hatype[, addr]]])` 表示，其中：

  - ifname - 指定设备名称的字符串。

  - proto - 一个用网络字节序表示的整数，指定以太网协议版本号。

  - pkttype - 指定数据包类型的整数（可选）：

    - `PACKET_HOST` （默认） - 数据包寻址到本地宿主机。

    - `PACKET_BROADCAST` - 物理层广播报文。

    - `PACKET_MULTIHOST` - 数据包发送到物理层多播地址。

    - `PACKET_OTHERHOST` - 被（处于混杂模式的）网卡驱动捕获的、发送到其他主机的数据包。

    - `PACKET_OUTGOING` - 来自本地主机的、回环到一个套接字的数据包。

  - hatype - 可选整数，指定 ARP 硬件地址类型。

  - addr - 可选的类字节串对象，用于指定硬件物理地址，其解释取决于各设备。

如果你在 IPv4/v6 套接字地址的 host 部分中使用了一个主机名，此程序可能会表现不确定行为，因为 Python 使用 DNS 解析返回的第一个地址。套接字地址在实际的 IPv4/v6 中以不同方式解析，根据 DNS 解析和/或 host 配置。为了确定行为，在 host 部分中使用数字地址。

所有的错误都抛出异常。对于无效参数类型和内存溢出异常情况可能抛出普通异常；从 Python 3.3 开始，与套接字或地址语义有关的错误抛出 `OSError` 或它的子类之一（常用 `socket.error`）。

可以用 `setblocking()` 设置非阻塞模式。一个基于超时的 generalization 通过 `settimeout()` 支持。

## 18.1.2. 模块内容

`socket` 模块导出以下元素。

### 18.1.2.1. 异常

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`

  `OSError` 的子类，当套接字发生超时，且事先已调用过 `settimeout()` （或隐式地通过 `setdefaulttimeout()` ）启用了超时，则会抛出此异常。附带的值是一个字符串，其值总是 「timed out」。

  3.3 版更變: 此类是 `OSError` 的子类。

### 18.1.2.2. 常量

> AF_* 和 SOCK_* 常量现在都在 `AddressFamily` 和 `SocketKind` 这两个 `IntEnum` 集合内。

> 3.4 版新加入.

`socket.``AF_UNIX`
`socket.``AF_INET`
`socket.``AF_INET6`

  这些常量表示地址（和协议）簇，用于 `socket()` 的第一个参数。如果 `AF_UNIX` 常量未定义，即表示不支持该协议。不同系统可能会有更多其他常量可用。

`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`

  这两个常量（如果已定义）可以与上述套接字类型结合使用，并允许你设置一些原子性的 flags （从而避免可能的竞争条件和单独调用的需要）。

  也參考

  Secure File Descriptor Handling （安全地处理文件描述符） 提供了更详尽的解释。

  Availability: 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` 可用。

`socket.``AF_CAN`
`socket.``PF_CAN`
`SOL_CAN_*`
`CAN_*`

  此列表内的许多常量，记载在 Linux 文档中，同时也定义在本 socket 模块中。

  Availability: Linux >= 2.6.25.

  3.3 版新加入.

`socket.``CAN_BCM`
`CAN_BCM_*`

  CAN 协议簇内的 CAN_BCM 是广播管理器（Bbroadcast Manager – BCM）协议，广播管理器常量在 Linux 文档中有所记载，在本 socket 模块中也有定义。

  Availability: Linux >= 2.6.25.

  3.4 版新加入.

`socket.``CAN_RAW_FD_FRAMES`

  Enables CAN FD support in a CAN_RAW socket. This is disabled by default. This allows your application to send both CAN and CAN FD frames; however, you one must accept both CAN and CAN FD frames when reading from the socket.

  此常量在 Linux 文档中有所记载。

  Availability: Linux >= 3.6.

  3.5 版新加入.

`socket.``AF_PACKET`
`socket.``PF_PACKET`
`PACKET_*`

  此列表内的许多常量，记载在 Linux 文档中，同时也定义在本 socket 模块中。

  Availability: Linux >= 2.2.

`socket.``AF_RDS`
`socket.``PF_RDS`
`socket.``SOL_RDS`
`RDS_*`

  此列表内的许多常量，记载在 Linux 文档中，同时也定义在本 socket 模块中。

  Availability: 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 socket API 导出的常量一致。更多信息请参阅 TIPC 文档。

`socket.``AF_ALG`
`socket.``SOL_ALG`
`ALG_*`

  用于 Linux 内核加密算法的常量。

  Availability: Linux >= 2.6.38.

  3.6 版新加入.

`socket.``AF_LINK`

  Availability: BSD, OSX.

  3.4 版新加入.

`socket.``has_ipv6`

  本常量为一个布尔值，该值指示当前平台是否支持 IPv6。

`socket.``BDADDR_ANY`
`socket.``BDADDR_LOCAL`

  这些是字符串常量，包含蓝牙地址，这些地址具有特殊含义。例如，当用 `BTPROTO_RFCOMM` 指定绑定套接字时， `BDADDR_ANY` 表示“任何地址”。

`socket.``HCI_FILTER`
`socket.``HCI_TIME_STAMP`
`socket.``HCI_DATA_DIR`

  与 `BTPROTO_HCI` 一起使用。 `HCI_FILTER` 在 NetBSD 或 DragonFlyBSD 上不可用。 `HCI_TIME_STAMP` 和 `HCI_DATA_DIR` 在 FreeBSD、NetBSD 或 DragonFlyBSD 上不可用。

### 18.1.2.3. 函数

#### 18.1.2.3.1. 创建套接字

下列函数都能创建 套接字对象.

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

  Create a new socket using the given address family, socket type and protocol number. The address family should be `AF_INET` (the default), `AF_INET6`, `AF_UNIX`, `AF_CAN`, `AF_PACKET`, or `AF_RDS`. The socket type should be `SOCK_STREAM` (the default), `SOCK_DGRAM`, `SOCK_RAW` or perhaps one of the other `SOCK_` constants. The protocol number is usually zero and may be omitted or in the case where the address family is `AF_CAN` the protocol should be one of `CAN_RAW` or `CAN_BCM`. If fileno is specified, the other arguments are ignored, causing the socket with the specified file descriptor to return. Unlike `socket.fromfd()`, fileno will return the same socket and not a duplicate. This may help close a detached socket using `socket.close()`.

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

  3.3 版更變: 添加了 AF_CAN 簇。添加了 AF_RDS 簇。

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

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

`socket.``socketpair`([family[, type[, proto]]])

  构建一对已连接的套接字对象，使用给定的地址簇、套接字类型和协议号。地址簇、套接字类型和协议号与上述 `socket()` 函数相同。默认地址簇为 `AF_UNIX` （需要当前平台支持，不支持则默认为 `AF_INET` ）。

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

  3.2 版更變: 现在，返回的套接字对象支持全部套接字 API，而不是全部 API 的一个子集。

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

  3.5 版更變: 添加了 Windows 支持。

`socket.``create_connection`(address[, timeout[, source_address]])

  连接到一个 TCP 服务，该服务正在侦听 Internet address （用二元组 `(host, port)` 表示）。连接后返回套接字对象。这是比 `socket.connect()` 更高级的函数：如果 host 是非数字主机名，它将尝试从 `AF_INET` 和 `AF_INET6` 解析它，然后依次尝试连接到所有可能的地址，直到连接成功。这使得编写兼容 IPv4 和 IPv6 的客户端变得容易。

  传入可选参数 timeout 可以在套接字实例上设置超时（在尝试连接前）。如果未提供 timeout，则使用由 `getdefaulttimeout()` 返回的全局默认超时设置。

  如果提供了 source_address，它必须为二元组 `(host, port)`，以便套接字在连接之前绑定为其源地址。如果 host 或 port 分别为 『』 或 0，则使用操作系统默认行为。

  3.2 版更變: 添加了*source_address* 参数

`socket.``fromfd`(fd, family, type, proto=0)

  复制文件描述符 fd （一个由文件对象的 `fileno()` 方法返回的整数），然后从结果中构建一个套接字对象。地址簇、套接字类型和协议号与上述 `socket()` 函数相同。文件描述符应指向一个套接字，但不会专门去检查——如果文件描述符是无效的，则对该对象的后续操作可能会失败。本函数很少用到，但是在将套接字作为标准输入或输出传递给程序（如 Unix inet 守护程序启动的服务器）时，可以使用本函数获取或设置套接字选项。套接字须处于阻塞模式。

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

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

`socket.``fromshare`(data)

  根据 `socket.share()` 方法获得的数据实例化套接字。套接字须处于阻塞模式。

  Availability: Windows.

  3.3 版新加入.

`socket.``SocketType`

  这是一个 Python 类型对象，表示套接字对象的类型。它等同于 `type(socket(...))`。

#### 18.1.2.3.2. 其他功能

`socket` 模块还提供各种与网络相关的服务：

`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 参数，以缩小返回的地址列表。向这些参数分别传入 0 表示保留全部结果范围。flags 参数可以是 `AI_*` 常量中的一个或多个，它会影响结果的计算和返回。例如，`AI_NUMERICHOST` 会禁用域名解析，此时如果 host 是域名，则会抛出错误。

  本函数返回的 5 元组列表具有以下结构：

  `(family, type, proto, canonname, sockaddr)`

  在这些元组中，family、type、proto 都是整数，可以用于传递给 `socket()` 函数。如果 flags 参数有一部分是 `AI_CANONNAME`，那么 canonname 将是表示 host 的规范名称的字符串。否则 canonname 将为空。sockaddr 是一个表示套接字地址的元组，具体格式取决于返回的 family （对于 `AF_INET`，是一个 `(address, port)` 二元组，对于 `AF_INET6`，是一个 `(address, port, flow info, scope id)` 四元组），可以用于传递给 `socket.connect()` 方法。

  下面的示例获取了 TCP 连接地址信息，假设该连接通过 80 端口连接至 `example.org` （如果系统未启用 IPv6，则结果可能会不同）：

      >>> socket.getaddrinfo("example.org", 80, proto=socket.IPPROTO_TCP)
      [(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_STREAM: 1>,
       6, '', ('2606:2800:220:1:248:1893:25c8:1946', 80, 0, 0)),
       (<AddressFamily.AF_INET: 2>, <SocketType.SOCK_STREAM: 1>,
       6, '', ('93.184.216.34', 80))]

  3.2 版更變: 现在可以使用关键字参数的形式来传递参数。

`socket.``getfqdn`([name])

  返回 name 的全限定域名 (Fully Qualified Domain Name – FQDN)。如果 name 省略或为空，则将其解释为本地主机。为了查找全限定名称，首先将检查由 `gethostbyaddr()` 返回的主机名，然后是主机的别名（如果存在）。选中第一个包含句点的名字。如果无法获取全限定域名，则返回由 `gethostname()` 返回的主机名。

`socket.``gethostbyname`(hostname)

  将主机名转换为 IPv4 地址格式。IPv4 地址以字符串格式返回，如 `'100.50.200.5'`。如果主机名本身是 IPv4 地址，则原样返回。更完整的接口请参考 `gethostbyname_ex()`。`gethostbyname()` 不支持 IPv6 域名解析，应使用 `getaddrinfo()` 来支持 IPv4/v6 双协议栈。

`socket.``gethostbyname_ex`(hostname)

  将主机名转换为 IPv4 地址格式的扩展接口。返回三元组 `(hostname, aliaslist, ipaddrlist)`，其中 hostname 是响应给定 ip_address 的主要主机名，aliaslist 是相同地址的其他可用主机名的列表（可能为空），而 ipaddrlist 是 IPv4 地址列表，包含相同主机名、相同接口的不同地址（通常是一个地址，但不总是如此）。`gethostbyname_ex()` 不支持 IPv6 名称解析，应使用 `getaddrinfo()` 来支持 IPv4/v6 双协议栈。

`socket.``gethostname`()

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

  注意： `gethostname()` 并不总是返回全限定域名，必要的话请使用 `getfqdn()`。

`socket.``gethostbyaddr`(ip_address)

  返回三元组 `(hostname, aliaslist, ipaddrlist)`，其中 hostname 是响应给定 ip_address 的主要主机名，aliaslist 是相同地址的其他可用主机名的列表（可能为空），而 ipaddrlist 是 IPv4/v6 地址列表，包含相同主机名、相同接口的不同地址（很可能仅包含一个地址）。要查询全限定域名，请使用函数 `getfqdn()`。`gethostbyaddr()` 支持 IPv4 和 IPv6。

`socket.``getnameinfo`(sockaddr, flags)

  将套接字地址 sockaddr 转换为二元组 `(host, port)`。host 的形式可能是全限定域名，或是由数字表示的地址，具体取决于 flags 的设置。同样，port 可以包含字符串格式的端口名称或数字格式的端口号。

`socket.``getprotobyname`(protocolname)

  将 Internet 协议名称（如 `'icmp'` ）转换为常量，该常量适用于 `socket()` 函数的第三个（可选）参数。通常只有在 「raw」 模式 (`SOCK_RAW`) 中打开的套接字才需要使用该常量。对于正常的套接字模式，协议省略或为零时，会自动选择正确的协议。

`socket.``getservbyname`(servicename[, protocolname])

  将 Internet 服务名称和协议名称转换为该服务的端口号。协议名称是可选的，如果提供的话应为 `'tcp'` 或 `'udp'`，否则将匹配出所有协议。

`socket.``getservbyport`(port[, protocolname])

  将 Internet 端口号和协议名称转换为该服务的服务名称。协议名称是可选的，如果提供的话应为 `'tcp'` 或 `'udp'`，否则将匹配出所有协议。

`socket.``ntohl`(x)

  将 32 位正整数从网络字节序转换为主机字节序。在主机字节序与网络字节序相同的计算机上，这是一个空操作。字节序不同将执行 4 字节交换操作。

`socket.``ntohs`(x)

  将 16 位正整数从网络字节序转换为主机字节序。在主机字节序与网络字节序相同的计算机上，这是一个空操作。字节序不同将执行 2 字节交换操作。

`socket.``htonl`(x)

  将 32 位正整数从主机字节序转换为网络字节序。在主机字节序与网络字节序相同的计算机上，这是一个空操作。字节序不同将执行 4 字节交换操作。

`socket.``htons`(x)

  将 16 位正整数从主机字节序转换为网络字节序。在主机字节序与网络字节序相同的计算机上，这是一个空操作。字节序不同将执行 2 字节交换操作。

`socket.``inet_aton`(ip_string)

  将 IPv4 地址从点分十进制字符串格式（如 『123.45.67.89』 ）转换为 32 位压缩二进制格式，转换后为字节对象，长度为四个字符。与那些使用标准 C 库，且需要 `struct in_addr` 类型的对象的程序交换信息时，此功能很有用。 该类型即此函数返回的 32 位压缩二进制的 C 类型。

  `inet_aton()` 也接受句点数少于三的字符串，详情请参阅 Unix 手册 inet(3)。

  如果传入本函数的 IPv4 地址字符串无效，则抛出 `OSError`。注意，具体什么样的地址有效取决于 `inet_aton()` 的底层 C 实现。

  `inet_aton()` 不支持 IPv6，在 IPv4/v6 双协议栈下应使用 `inet_pton()` 来代替。

`socket.``inet_ntoa`(packed_ip)

  将 32 位压缩 IPv4 地址（一个 类字节对象，长 4 个字节）转换为标准的点分十进制字符串形式（如 『123.45.67.89』 ）。与那些使用标准 C 库，且需要 `struct in_addr` 类型的对象的程序交换信息时，本函数很有用。 该类型即本函数参数中的 32 位压缩二进制数据的 C 类型。

  如果传入本函数的字节序列长度不是 4 个字节，则抛出 `OSError`。`inet_ntoa()` 不支持 IPv6，在 IPv4/v6 双协议栈下应使用 `inet_ntop()` 来代替。

  3.5 版更變: 现在支持可写的 字节类对象。

`socket.``inet_pton`(address_family, ip_string)

  将特定地址簇的 IP 地址（字符串）转换为压缩二进制格式。当库或网络协议需要接受 `struct in_addr` 类型的对象（类似 `inet_aton()` ）或 `struct in6_addr` 类型的对象时，`inet_pton()` 很有用。

  目前 address_family 支持 `AF_INET` 和 `AF_INET6`。如果 IP 地址字符串 ip_string 无效，则抛出 `OSError`。注意，具体什么地址有效取决于 address_family 的值和 `inet_pton()` 的底层实现。

  Availability: Unix (maybe not all platforms), Windows.

  3.4 版更變: 添加了 Windows 支持

`socket.``inet_ntop`(address_family, packed_ip)

  将压缩 IP 地址（一个 类字节对象，数个字节长）转换为标准的、特定地址簇的字符串形式（如 `'7.10.0.5'` 或 `'5aef:2b::8'` ）。当库或网络协议返回 `struct in_addr` 类型的对象（类似 `inet_ntoa()` ）或 `struct in6_addr` 类型的对象时，`inet_ntop()` 很有用。

  目前 address_family 支持 `AF_INET` 和 `AF_INET6`。如果字节对象 packed_ip 与指定的地址簇长度不符，则抛出 `ValueError`。针对 `inet_ntop()` 调用的错误则抛出 `OSError`。

  Availability: Unix (maybe not all platforms), Windows.

  3.4 版更變: 添加了 Windows 支持

  3.5 版更變: 现在支持可写的 字节类对象。

`socket.``CMSG_LEN`(length)

  返回给定 length 所关联数据的辅助数据项的总长度（不带尾部填充）。此值通常用作 `recvmsg()` 接收一个辅助数据项的缓冲区大小，但是 RFC 3542 要求可移植应用程序使用 `CMSG_SPACE()`，以此将尾部填充的空间计入，即使该项在缓冲区的最后。如果 length 超出允许范围，则抛出 `OverflowError`。

  Availability: most Unix platforms, possibly others.

  3.3 版新加入.

`socket.``CMSG_SPACE`(length)

  返回 `recvmsg()` 所需的缓冲区大小，以接收给定 length 所关联数据的辅助数据项，带有尾部填充。接收多个项目所需的缓冲区空间是关联数据长度的 `CMSG_SPACE()` 值的总和。如果 length 超出允许范围，则抛出 `OverflowError`。

  请注意，某些系统可能支持辅助数据，但不提供本函数。还需注意，如果使用本函数的结果来设置缓冲区大小，可能无法精确限制可接收的辅助数据量，因为可能会有其他数据写入尾部填充区域。

  Availability: most Unix platforms, possibly others.

  3.3 版新加入.

`socket.``getdefaulttimeout`()

  返回用于新套接字对象的默认超时（以秒为单位的浮点数）。值 `None` 表示新套接字对象没有超时。首次导入 socket 模块时，默认值为 `None`。

`socket.``setdefaulttimeout`(timeout)

  设置用于新套接字对象的默认超时（以秒为单位的浮点数）。首次导入 socket 模块时，默认值为 `None`。可能的取值及其各自的含义请参阅 `settimeout()`。

`socket.``sethostname`(name)

  将计算机的主机名设置为 name。如果权限不足将抛出 `OSError`。

  Availability: Unix.

  3.3 版新加入.

`socket.``if_nameindex`()

  返回一个列表，包含网络接口（网卡）信息二元组（整数索引，名称字符串）。系统调用失败则抛出 `OSError`。

  Availability: Unix.

  3.3 版新加入.

`socket.``if_nametoindex`(if_name)

  返回网络接口名称相对应的索引号。如果没有所给名称的接口，则抛出 `OSError`。

  Availability: Unix.

  3.3 版新加入.

`socket.``if_indextoname`(if_index)

  返回网络接口索引号相对应的接口名称。如果没有所给索引号的接口，则抛出 `OSError`。

  Availability: Unix.

  3.3 版新加入.

## 18.1.3. 套接字对象

套接字对象具有以下方法。除了 `makefile()`，其他都与套接字专用的 Unix 系统调用相对应。

3.2 版更變: 添加了对 上下文管理器 协议的支持。退出上下文管理器与调用 `close()` 等效。

`socket.``accept`()

  接受一个连接。此 scoket 必须绑定到一个地址上并且监听连接。返回值是一个 `(conn, address)` 对，其中 conn 是一个 新 的套接字对象，用于在此连接上收发数据，address 是连接另一端的套接字所绑定的地址。

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

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

  3.5 版更變: 如果系统调用被中断，但信号处理程序没有触发异常，此方法现在会重试系统调用，而不是触发 `InterruptedError` 异常 (原因详见 PEP 475)。

`socket.``bind`(address)

  将套接字绑定到 address。套接字必须尚未绑定。（ address 的格式取决于地址簇 —— 参见上文）

`socket.``close`()

  将套接字标记为关闭。当 `makefile()` 创建的所有文件对象都关闭时，底层系统资源（如文件描述符）也将关闭。一旦上述情况发生，将来对套接字对象的所有操作都会失败。对端将接收不到任何数据（清空队列数据后）。

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

  3.6 版更變: 现在，如果底层的 `close()` 调用出错，会抛出 `OSError`。

  備註

  `close()` 释放与连接相关联的资源，但不一定立即关闭连接。如果需要及时关闭连接，请在调用 `close()` 之前调用 `shutdown()`。

`socket.``connect`(address)

  连接到 address 处的远程套接字。（ address 的格式取决于地址簇 —— 参见上文）

  如果连接被信号中断，则本方法将等待，直到连接完成。如果信号处理程序未抛出异常，且套接字阻塞中或已超时，则在超时后抛出 `socket.timeout`。对于非阻塞套接字，如果连接被信号中断，则本方法将抛出 `InterruptedError` 异常（或信号处理程序抛出的异常）。

  3.5 版更變: 本方法现在将等待，直到连接完成，而不是在以下情况抛出 `InterruptedError` 异常。该情况为，连接被信号中断，信号处理程序未抛出异常，且套接字阻塞中或已超时（具体解释请参阅 PEP 475 ）。

`socket.``connect_ex`(address)

  类似于 `connect(address)`，但是对于 C 级别的 `connect()` 调用返回的错误，本函数将返回错误指示器，而不是抛出异常（对于其他问题，如“找不到主机”，仍然可以抛出异常）。如果操作成功，则错误指示器为 `0`，否则为 `errno` 变量的值。这对支持如异步连接很有用。

`socket.``detach`()

  将套接字对象置于关闭状态，而底层的文件描述符实际并不关闭。返回该文件描述符，使其可以重新用于其他目的。

  3.2 版新加入.

`socket.``dup`()

  创建套接字的副本。

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

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

`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` ）。

`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 会被置为 0），它指定系统允许暂未 accept 的连接数，超过后将拒绝新连接。未指定则自动设为合理的默认值。

  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)。

`socket.``recvmsg`(bufsize[, ancbufsize[, flags]])

  从套接字接收普通数据（至多 bufsize 字节）和辅助数据。ancbufsize 参数设置用于接收辅助数据的内部缓冲区的大小（以字节为单位），默认为 0，表示不接收辅助数据。可以使用 `CMSG_SPACE()` 或 `CMSG_LEN()` 计算辅助数据缓冲区的合适大小，无法放入缓冲区的项目可能会被截断或丢弃。flags 参数默认为 0，其含义与 `recv()` 中的相同。

  返回值是一个四元组： `(data, ancdata, msg_flags, address)`。data 项是一个 `bytes` 对象，用于保存接收到的非辅助数据。ancdata 项是零个或多个元组 `(cmsg_level, cmsg_type, cmsg_data)` 组成的列表，表示接收到的辅助数据（控制消息）：cmsg_level 和 cmsg_type 是分别表示协议级别和协议类型的整数，而 cmsg_data 是保存相关数据的 `bytes` 对象。msg_flags 项由各种标志按位或组成，表示接收消息的情况，详细信息请参阅系统文档。如果接收端套接字断开连接，则 address 是发送端套接字的地址（如果有），否则该值无指定。

  某些系统上可以利用 `AF_UNIX` 套接字通过 `sendmsg()` 和 `recvmsg()` 在进程之间传递文件描述符。使用此功能时（通常仅限于 `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.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
          return msg, list(fds)

  Availability: most Unix platforms, possibly others.

  3.3 版新加入.

  3.5 版更變: 如果系统调用被中断，但信号处理程序没有触发异常，此方法现在会重试系统调用，而不是触发 `InterruptedError` 异常 (原因详见 PEP 475)。

`socket.``recvmsg_into`(buffers[, ancbufsize[, flags]])

  从套接字接收普通数据和辅助数据，其行为与 `recvmsg()` 相同，但将非辅助数据分散到一系列缓冲区中，而不是返回新的字节对象。buffers 参数必须是可迭代对象，它迭代出可供写入的缓冲区（如 `bytearray` 对象），这些缓冲区将被连续的非辅助数据块填充，直到数据全部写完或缓冲区用完为止。在允许使用的缓冲区数量上，操作系统可能会有限制（ `sysconf()` 的 `SC_IOV_MAX` 值）。ancbufsize 和 flags 参数的含义与 `recvmsg()` 中的相同。

  返回值为四元组： `(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---')]

  Availability: most Unix platforms, possibly others.

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

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

  Availability: most Unix platforms, possibly others.

  3.3 版新加入.

  3.5 版更變: 如果系统调用被中断，但信号处理程序没有触发异常，此方法现在会重试系统调用，而不是触发 `InterruptedError` 异常 (原因详见 PEP 475)。

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

  为 `AF_ALG` 套接字定制的 `sendmsg()` 版本。可为 `AF_ALG` 套接字设置模式、IV、AEAD 关联数据的长度和标志位。

  Availability: 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)`

`socket.``settimeout`(value)

  为阻塞套接字的操作设置超时。value 参数可以是非负浮点数，表示秒，也可以是 `None`。如果赋为一个非零值，那么如果在操作完成前超过了超时时间 value，后续的套接字操作将抛出 `timeout` 异常。如果赋为 0，则套接字将处于非阻塞模式。如果指定为 `None`，则套接字将处于阻塞模式。

  更多信息请查阅 关于套接字超时的说明。

`socket.``setsockopt`(level, optname, value: int)

`socket.``setsockopt`(level, optname, value: buffer)

`socket.``setsockopt`(level, optname, None, optlen: int)

  Set the value of the given socket option (see the Unix manual page setsockopt(2)). The needed symbolic constants are defined in the `socket` module (`SO_*` etc.). The value can be an integer, `None` or a bytes-like object representing a buffer. In the later case it is up to the caller to ensure that the bytestring contains the proper bits (see the optional built-in module `struct` for a way to encode C structures as bytestrings). When value is set to `None`, optlen argument is required. It’s equivalent to call setsockopt C function with optval=NULL and optlen=optlen.

  3.5 版更變: 现在支持可写的 字节类对象。

  3.6 版更變: 添加了 setsockopt(level, optname, None, optlen: int) 调用形式。

`socket.``shutdown`(how)

  关闭一半或全部的连接。如果 how 为 `SHUT_RD`，则后续不再允许接收。如果 how 为 `SHUT_WR`，则后续不再允许发送。如果 how 为 `SHUT_RDWR`，则后续的发送和接收都不允许。

`socket.``share`(process_id)

  复制套接字，并准备将其与目标进程共享。目标进程必须以 process_id 形式提供。然后可以利用某种形式的进程间通信，将返回的字节对象传递给目标进程，还可以使用 `fromshare()` 在新进程中重新创建套接字。一旦本方法调用完毕，就可以安全地将套接字关闭，因为操作系统已经为目标进程复制了该套接字。

  Availability: Windows.

  3.3 版新加入.

注意此处没有 `read()` 或 `write()` 方法，请使用不带 flags 参数的 `recv()` 和 `send()` 来替代。

套接字对象还具有以下（只读）属性，这些属性与传入 `socket` 构造函数的值相对应。

`socket.``family`

  套接字的协议簇

`socket.``type`

  套接字的类型

`socket.``proto`

  套接字的协议。

## 18.1.4. 关于套接字超时的说明

一个套接字对象可以处于以下三种模式之一：阻塞、非阻塞或超时。套接字默认以阻塞模式创建，但是可以调用 `setdefaulttimeout()` 来更改。

- 在 blocking mode （阻塞模式）中，操作将阻塞，直到操作完成或系统返回错误（如连接超时）。

- 在 non-blocking mode （非阻塞模式）中，如果操作无法立即完成，则操作将失败（不幸的是，不同系统返回的错误不同）：位于 `select` 中的函数可用于了解套接字何时以及是否可以读取或写入。

- 在 timeout mode （超时模式）下，如果无法在指定的超时内完成操作（抛出 `timeout` 异常），或如果系统返回错误，则操作将失败。

備註

在操作系统层面上，超时模式 下的套接字在内部都设置为非阻塞模式。同时，阻塞和超时模式在文件描述符和套接字对象之间共享，这些描述符和对象均应指向同一个网络端点。如果，比如你决定使用套接字的 `fileno()`，这一实现细节可能导致明显的结果。

### 18.1.4.1. 超时与 `connect` 方法

`connect()` 操作也受超时设置的约束，通常建议在调用 `connect()` 之前调用 `settimeout()`，或将超时参数直接传递给 `create_connection()`。但是，无论 Python 套接字超时设置如何，系统网络栈都有可能返回自带的连接超时错误。

### 18.1.4.2. 超时与 `accept` 方法

如果 `getdefaulttimeout()` 的值不是 `None`，则 `accept()` 方法返回的套接字将继承该超时值。若是 None，返回的套接字行为取决于侦听套接字的设置：

- 如果侦听套接字处于 阻塞模式 或 超时模式，则 `accept()` 返回的套接字处于 阻塞模式；

- 如果侦听套接字处于 非阻塞模式，那么 `accept()` 返回的套接字是阻塞还是非阻塞取决于操作系统。如果要确保跨平台时的正确行为，建议手动覆盖此设置。

## 18.1.5. 示例

以下是 4 个使用 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 packages
    s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

    # receive a package
    print(s.recvfrom(65565))

    # disabled promiscuous mode
    s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

The last example shows how to use the socket interface to communicate to a CAN network using the raw socket protocol. To use CAN with the broadcast manager protocol instead, open a socket with:

    socket.socket(socket.AF_CAN, socket.SOCK_DGRAM, socket.CAN_BCM)

在绑定 (`CAN_RAW`) 或连接 (`CAN_BCM`) socket 之后，你将可以在 socket 对象上正常使用 `socket.send()` 以及 `socket.recv()` 操作（及同类操作）。

This example might require special privileges:

    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 et al,

两篇文章都在 UNIX 开发者手册，补充文档 1（第 PS1:7 和 PS1:8 节）中。那些特定于平台的参考资料，它们包含与套接字有关的各种系统调用，也是套接字语义细节的宝贵信息来源。对于 Unix，请参考手册页。对于 Windows，请参阅 WinSock（或 Winsock 2）规范。如果需要支持 IPv6 的 API，读者可能希望参考 RFC 3493，标题为 Basic Socket Interface Extensions for IPv6。