17.2. socket — 底层网络接口

This module provides access to the BSD socket interface. It is available on all modern Unix systems, Windows, Mac OS X, BeOS, OS/2, and probably additional platforms.

注解

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

For an introduction to socket programming (in C), see the following papers: An Introductory 4.3BSD Interprocess Communication Tutorial, by Stuart Sechrest and An Advanced 4.3BSD Interprocess Communication Tutorial, by Samuel J. Leffler et al, both in the UNIX Programmer’s Manual, Supplementary Documents 1 (sections PS1:7 and PS1:8). The platform-specific reference material for the various socket-related system calls are also a valuable source of information on the details of socket semantics. For Unix, refer to the manual pages; for Windows, see the WinSock (or Winsock 2) specification. For IPv6-ready APIs, readers may want to refer to RFC 3493 titled Basic Socket Interface Extensions for IPv6.

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

Socket addresses are represented as follows: A single string is used for the AF_UNIX address family. A pair (host, port) is used for the AF_INET address family, where host is a string representing either a hostname in Internet domain notation like 'daring.cwi.nl' or an IPv4 address like '100.50.200.5', and port is an integer. For AF_INET6 address family, a four-tuple (host, port, flowinfo, scopeid) is used, where flowinfo and scopeid represents sin6_flowinfo and sin6_scope_id member in struct sockaddr_in6 in C. For socket module methods, flowinfo and scopeid can be omitted just for backward compatibility. Note, however, omission of scopeid can cause problems in manipulating scoped IPv6 addresses. Other address families are currently not supported. The address format required by a particular socket object is automatically selected based on the address family specified when the socket object was created.

For IPv4 addresses, two special forms are accepted instead of a host address: the empty string represents INADDR_ANY, and the string '<broadcast>' represents INADDR_BROADCAST. The behavior is not available for IPv6 for backward compatibility, therefore, you may want to avoid these if you intend to support IPv6 with your Python programs.

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

2.5 新版功能: AF_NETLINK sockets are represented as pairs pid, groups.

2.6 新版功能: Linux-only support for TIPC is also available using the AF_TIPC address family. TIPC is an open, non-IP based networked protocol designed for use in clustered computer environments. Addresses are represented by a tuple, and the fields depend on the address type. The general tuple form is (addr_type, v1, v2, v3 [, scope]), where:

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

All errors raise exceptions. The normal exceptions for invalid argument types and out-of-memory conditions can be raised; errors related to socket or address semantics raise the error socket.error.

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

The module socket exports the following constants and functions:

exception socket.error

This exception is raised for socket-related errors. The accompanying value is either a string telling what went wrong or a pair (errno, string) representing an error returned by a system call, similar to the value accompanying os.error. See the module errno, which contains names for the error codes defined by the underlying operating system.

在 2.6 版更改: socket.error is now a child class of IOError.

exception socket.herror

This exception is raised for address-related errors, i.e. for functions that use h_errno in the C API, including gethostbyname_ex() and gethostbyaddr().

The accompanying value is a pair (h_errno, string) representing an error returned by a library call. string represents the description of h_errno, as returned by the hstrerror() C function.

exception socket.gaierror

This exception is raised for address-related errors, for getaddrinfo() and getnameinfo(). The accompanying value is a pair (error, string) representing an error returned by a library call. string represents the description of error, as returned by the gai_strerror() C function. The error value will match one of the EAI_* constants defined in this module.

exception socket.timeout

This exception is raised when a timeout occurs on a socket which has had timeouts enabled via a prior call to settimeout(). The accompanying value is a string whose value is currently always “timed out”.

2.3 新版功能.

socket.AF_UNIX
socket.AF_INET
socket.AF_INET6

These constants represent the address (and protocol) families, used for the first argument to socket(). If the AF_UNIX constant is not defined then this protocol is unsupported.

socket.SOCK_STREAM
socket.SOCK_DGRAM
socket.SOCK_RAW
socket.SOCK_RDM
socket.SOCK_SEQPACKET

These constants represent the socket types, used for the second argument to socket(). (Only SOCK_STREAM and SOCK_DGRAM appear to be generally useful.)

SO_*
socket.SOMAXCONN
MSG_*
SOL_*
IPPROTO_*
IPPORT_*
INADDR_*
IP_*
IPV6_*
EAI_*
AI_*
NI_*
TCP_*

此列表内的许多常量,记载在 Unix 文档中的套接字和/或 IP 协议部分,同时也定义在本 socket 模块中。它们通常用于套接字对象的 setsockopt()getsockopt() 方法的参数中。在大多数情况下,仅那些在 Unix 头文件中有定义的符号会在本模块中定义,部分符号提供了默认值。

SIO_*
RCVALL_*

Windows 的 WSAIoctl() 的常量。这些常量用于套接字对象的 ioctl() 方法的参数。

2.6 新版功能.

TIPC_*

TIPC 相关常量,与 C socket API 导出的常量一致。更多信息请参阅 TIPC 文档。

2.6 新版功能.

socket.has_ipv6

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

2.3 新版功能.

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

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

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

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

2.6 新版功能.

在 2.7 版更改: 添加了*source_address* 参数

socket.getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]])

host/port 参数转换为 5 元组的序列,其中包含创建(连接到某服务的)套接字所需的所有参数。host 是域名,是字符串格式的 IPv4/v6 地址或 Noneport 是字符串格式的服务名称,如 'http' 、端口号(数字)或 None。传入 None 作为 hostport 的值,相当于将 NULL 传递给底层 C API。

The family, socktype and proto arguments can be optionally specified in order to narrow the list of addresses returned. By default, their value is 0, meaning that the full range of results is selected. The flags argument can be one or several of the AI_* constants, and will influence how results are computed and returned. Its default value is 0. For example, AI_NUMERICHOST will disable domain name resolution and will raise an error if host is a domain name.

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

(family, socktype, proto, canonname, sockaddr)

In these tuples, family, socktype, proto are all integers and are meant to be passed to the socket() function. canonname will be a string representing the canonical name of the host if AI_CANONNAME is part of the flags argument; else canonname will be empty. sockaddr is a tuple describing a socket address, whose format depends on the returned family (a (address, port) 2-tuple for AF_INET, a (address, port, flow info, scope id) 4-tuple for AF_INET6), and is meant to be passed to the socket.connect() method.

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

>>> socket.getaddrinfo("example.org", 80, 0, 0, socket.IPPROTO_TCP)
[(10, 1, 6, '', ('2606:2800:220:1:248:1893:25c8:1946', 80, 0, 0)),
 (2, 1, 6, '', ('93.184.216.34', 80))]

2.2 新版功能.

socket.getfqdn([name])

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

2.0 新版功能.

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 解释器的机器的主机名。

If you want to know the current machine’s IP address, you may want to use gethostbyname(gethostname()). This operation assumes that there is a valid address-to-host mapping for the host, and the assumption does not always hold.

Note: gethostname() doesn’t always return the fully qualified domain name; use getfqdn() (see above).

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 可以包含字符串格式的端口名称或数字格式的端口号。

2.2 新版功能.

socket.getprotobyname(protocolname)

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

socket.getservbyname(servicename[, protocolname])

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

socket.getservbyport(port[, protocolname])

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

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

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 or AF_UNIX. The socket type should be SOCK_STREAM (the default), SOCK_DGRAM or perhaps one of the other SOCK_ constants. The protocol number is usually zero and may be omitted in that case.

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

Build a pair of connected socket objects using the given address family, socket type, and protocol number. Address family, socket type, and protocol number are as for the socket() function above. The default family is AF_UNIX if defined on the platform; otherwise, the default is AF_INET. Availability: Unix.

2.4 新版功能.

socket.fromfd(fd, family, type[, proto])

Duplicate the file descriptor fd (an integer as returned by a file object’s fileno() method) and build a socket object from the result. Address family, socket type and protocol number are as for the socket() function above. The file descriptor should refer to a socket, but this is not checked — subsequent operations on the object may fail if the file descriptor is invalid. This function is rarely needed, but can be used to get or set socket options on a socket passed to a program as standard input or output (such as a server started by the Unix inet daemon). The socket is assumed to be in blocking mode. Availability: Unix.

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)

Convert an IPv4 address from dotted-quad string format (for example, ‘123.45.67.89’) to 32-bit packed binary format, as a string four characters in length. This is useful when conversing with a program that uses the standard C library and needs objects of type struct in_addr, which is the C type for the 32-bit packed binary this function returns.

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

If the IPv4 address string passed to this function is invalid, socket.error will be raised. Note that exactly what is valid depends on the underlying C implementation of inet_aton().

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

socket.inet_ntoa(packed_ip)

Convert a 32-bit packed IPv4 address (a string four characters in length) to its standard dotted-quad string representation (for example, ‘123.45.67.89’). This is useful when conversing with a program that uses the standard C library and needs objects of type struct in_addr, which is the C type for the 32-bit packed binary data this function takes as an argument.

If the string passed to this function is not exactly 4 bytes in length, socket.error will be raised. inet_ntoa() does not support IPv6, and inet_ntop() should be used instead for IPv4/v6 dual stack support.

socket.inet_pton(address_family, ip_string)

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

Supported values for address_family are currently AF_INET and AF_INET6. If the IP address string ip_string is invalid, socket.error will be raised. Note that exactly what is valid depends on both the value of address_family and the underlying implementation of inet_pton().

Availability: Unix (maybe not all platforms).

2.3 新版功能.

socket.inet_ntop(address_family, packed_ip)

Convert a packed IP address (a string of some number of characters) to its standard, family-specific string representation (for example, '7.10.0.5' or '5aef:2b::8') inet_ntop() is useful when a library or network protocol returns an object of type struct in_addr (similar to inet_ntoa()) or struct in6_addr.

Supported values for address_family are currently AF_INET and AF_INET6. If the string packed_ip is not the correct length for the specified address family, ValueError will be raised. A socket.error is raised for errors from the call to inet_ntop().

Availability: Unix (maybe not all platforms).

2.3 新版功能.

socket.getdefaulttimeout()

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

2.3 新版功能.

socket.setdefaulttimeout(timeout)

Set the default timeout in seconds (float) for new socket objects. A value of None indicates that new socket objects have no timeout. When the socket module is first imported, the default is None.

2.3 新版功能.

socket.SocketType

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

参见

Module SocketServer

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

模块 ssl

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

17.2.1. 套接字对象

Socket objects have the following methods. Except for makefile() these correspond to Unix system calls applicable to sockets.

socket.accept()

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

socket.bind(address)

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

注解

This method has historically accepted a pair of parameters for AF_INET addresses instead of only a tuple. This was never intentional and is no longer available in Python 2.0 and later.

socket.close()

Close the socket. All future operations on the socket object will fail. The remote end will receive no more data (after queued data is flushed). Sockets are automatically closed when they are garbage-collected.

注解

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

socket.connect(address)

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

注解

This method has historically accepted a pair of parameters for AF_INET addresses instead of only a tuple. This was never intentional and is no longer available in Python 2.0 and later.

socket.connect_ex(address)

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

注解

This method has historically accepted a pair of parameters for AF_INET addresses instead of only a tuple. This was never intentional and is no longer available in Python 2.0 and later.

socket.fileno()

Return the socket’s file descriptor (a small integer). This is useful with select.select().

在 Windows 下,此方法返回的小整数在允许使用文件描述符的地方无法使用(如 os.fdopen() )。Unix 无此限制。

socket.getpeername()

返回套接字连接到的远程地址。举例而言,这可以用于查找远程 IPv4/v6 套接字的端口号。(返回的地址格式取决于地址簇 —— 参见上文。)部分系统不支持此函数。

socket.getsockname()

返回套接字本身的地址。举例而言,这可以用于查找 IPv4/v6 套接字的端口号。(返回的地址格式取决于地址簇 —— 参见上文。)

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

Return the value of the given socket option (see the Unix man page getsockopt(2)). The needed symbolic constants (SO_* etc.) are defined in this module. If buflen is absent, an integer option is assumed and its integer value is returned by the function. If buflen is present, it specifies the maximum length of the buffer used to receive the option in, and this buffer is returned as a string. It is up to the caller to decode the contents of the buffer (see the optional built-in module struct for a way to decode C structures encoded as strings).

socket.ioctl(control, option)
平台

Windows

ioctl() 方法是 WSAIoctl 系统接口的有限接口。请参考 Win32 文档 以获取更多信息。

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

2.6 新版功能.

socket.listen(backlog)

Listen for connections made to the socket. The backlog argument specifies the maximum number of queued connections and should be at least 0; the maximum value is system-dependent (usually 5), the minimum value is forced to 0.

socket.makefile([mode[, bufsize]])

Return a file object associated with the socket. (File objects are described in File Objects.) The file object does not close the socket explicitly when its close() method is called, but only removes its reference to the socket object, so that the socket will be closed if it is not referenced from anywhere else.

The socket must be in blocking mode (it can not have a timeout). The optional mode and bufsize arguments are interpreted the same way as by the built-in file() function.

注解

在 Windows 上,由 makefile() 创建的文件类对象无法作为带文件描述符的文件对象使用,如无法作为 subprocess.Popen() 的流参数。

socket.recv(bufsize[, flags])

Receive data from the socket. The return value is a string representing the data received. The maximum amount of data to be received at once is specified by bufsize. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.

注解

为了最佳匹配硬件和网络的实际情况,bufsize 的值应为 2 的相对较小的幂,如 4096。

socket.recvfrom(bufsize[, flags])

Receive data from the socket. The return value is a pair (string, address) where string is a string representing the data received and address is the address of the socket sending the data. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero. (The format of address depends on the address family — see above.)

socket.recvfrom_into(buffer[, nbytes[, flags]])

Receive data from the socket, writing it into buffer instead of creating a new string. The return value is a pair (nbytes, address) where nbytes is the number of bytes received and address is the address of the socket sending the data. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero. (The format of address depends on the address family — see above.)

2.5 新版功能.

socket.recv_into(buffer[, nbytes[, flags]])

Receive up to nbytes bytes from the socket, storing the data into a buffer rather than creating a new string. If nbytes is not specified (or 0), receive up to the size available in the given buffer. Returns the number of bytes received. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.

2.5 新版功能.

socket.send(string[, flags])

Send data to the socket. The socket must be connected to a remote socket. The optional flags argument has the same meaning as for recv() above. Returns the number of bytes sent. Applications are responsible for checking that all data has been sent; if only some of the data was transmitted, the application needs to attempt delivery of the remaining data. For further information on this concept, consult the 套接字编程指南.

socket.sendall(string[, flags])

Send data to the socket. The socket must be connected to a remote socket. The optional flags argument has the same meaning as for recv() above. Unlike send(), this method continues to send data from string until either all data has been sent or an error occurs. None is returned on success. On error, an exception is raised, and there is no way to determine how much data, if any, was successfully sent.

socket.sendto(string, address)
socket.sendto(string, flags, address)

发送数据给套接字。本套接字不应连接到远程套接字,而应由 address 指定目标套接字。可选参数 flags 的含义与上述 recv() 中的相同。本方法返回已发送的字节数。( address 的格式取决于地址簇 —— 参见上文。)

socket.setblocking(flag)

Set blocking or non-blocking mode of the socket: if flag is 0, the socket is set to non-blocking, else to blocking mode. Initially all sockets are in blocking mode. In non-blocking mode, if a recv() call doesn’t find any data, or if a send() call can’t immediately dispose of the data, an error exception is raised; in blocking mode, the calls block until they can proceed. s.setblocking(0) is equivalent to s.settimeout(0.0); s.setblocking(1) is equivalent to s.settimeout(None).

socket.settimeout(value)

Set a timeout on blocking socket operations. The value argument can be a nonnegative float expressing seconds, or None. If a float is given, subsequent socket operations will raise a timeout exception if the timeout period value has elapsed before the operation has completed. Setting a timeout of None disables timeouts on socket operations. s.settimeout(0.0) is equivalent to s.setblocking(0); s.settimeout(None) is equivalent to s.setblocking(1).

2.3 新版功能.

socket.gettimeout()

返回套接字操作相关的超时秒数(浮点数),未设置超时则返回 None。它反映最后一次调用 setblocking()settimeout() 后的设置。

2.3 新版功能.

Some notes on socket blocking and timeouts: A socket object can be in one of three modes: blocking, non-blocking, or timeout. Sockets are always created in blocking mode. In blocking mode, operations block until complete or the system returns an error (such as connection timed out). In non-blocking mode, operations fail (with an error that is unfortunately system-dependent) if they cannot be completed immediately. In timeout mode, operations fail if they cannot be completed within the timeout specified for the socket or if the system returns an error. The setblocking() method is simply a shorthand for certain settimeout() calls.

Timeout mode internally sets the socket in non-blocking mode. The blocking and timeout modes are shared between file descriptors and socket objects that refer to the same network endpoint. A consequence of this is that file objects returned by the makefile() method must only be used when the socket is in blocking mode; in timeout or non-blocking mode file operations that cannot be completed immediately will fail.

Note that the connect() operation is subject to the timeout setting, and in general it is recommended to call settimeout() before calling connect() or pass a timeout parameter to create_connection(). The system network stack may return a connection timeout error of its own regardless of any Python socket timeout setting.

socket.setsockopt(level, optname, value)

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 or a string representing a buffer. In the latter case it is up to the caller to ensure that the string contains the proper bits (see the optional built-in module struct for a way to encode C structures as strings).

socket.shutdown(how)

Shut down one or both halves of the connection. If how is SHUT_RD, further receives are disallowed. If how is SHUT_WR, further sends are disallowed. If how is SHUT_RDWR, further sends and receives are disallowed. Depending on the platform, shutting down one half of the connection can also close the opposite half (e.g. on Mac OS X, shutdown(SHUT_WR) does not allow further reads on the other end of the connection).

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

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

socket.family

套接字的协议簇

2.5 新版功能.

socket.type

套接字的类型

2.5 新版功能.

socket.proto

套接字的协议。

2.5 新版功能.

17.2.2. 示例

以下是 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
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.sendall(data)
conn.close()
# Echo client program
import socket

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
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 socket.error as msg:
        s = None
        continue
    try:
        s.bind(sa)
        s.listen(1)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.send(data)
conn.close()
# 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 socket.error as msg:
        s = None
        continue
    try:
        s.connect(sa)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)

The last example shows how to write a very simple network sniffer with raw sockets on Windows. The example requires administrator privileges to modify the interface:

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)

如果多次运行示例,且两次运行间隔很短,可能引发此错误:

socket.error: [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 状态的本地套接字重新使用,而不必等到固有的超时到期。