socket --- 底層網(wǎng)絡(luò)接口?

源代碼: Lib/socket.py


這個模塊提供了訪問 BSD 套接字 的接口。在所有現(xiàn)代 Unix 系統(tǒng)、Windows、macOS 和其他一些平臺上可用。

備注

一些行為可能因平臺不同而異,因為調(diào)用的是操作系統(tǒng)的套接字API。

這個Python接口是用Python的面向?qū)ο箫L(fēng)格對Unix系統(tǒng)調(diào)用和套接字庫接口的直譯:函數(shù) socket() 返回一個 套接字對象 ,其方法是對各種套接字系統(tǒng)調(diào)用的實現(xiàn)。形參類型一般與C接口相比更高級:例如在Python文件 read()write() 操作中,接收操作的緩沖區(qū)分配是自動的,發(fā)送操作的緩沖區(qū)長度是隱式的。

參見

模塊 socketserver

用于簡化網(wǎng)絡(luò)服務(wù)端編寫的類。

模塊 ssl

套接字對象的TLS/SSL封裝。

套接字協(xié)議族?

根據(jù)系統(tǒng)以及構(gòu)建選項,此模塊提供了各種套接字協(xié)議簇。

特定的套接字對象需要的地址格式將根據(jù)此套接字對象被創(chuàng)建時指定的地址族被自動選擇。套接字地址表示如下:

  • 一個綁定在文件系統(tǒng)節(jié)點上的 AF_UNIX 套接字的地址表示為一個字符串,使用文件系統(tǒng)字符編碼和 'surrogateescape' 錯誤回調(diào)方法(see PEP 383)。一個地址在 Linux 的抽象命名空間被返回為帶有初始的 null 字節(jié)的 字節(jié)類對象 ;注意在這個命名空間種的套接字可能與普通文件系統(tǒng)套接字通信,所以打算運行在 Linux 上的程序可能需要解決兩種地址類型。當(dāng)傳遞為參數(shù)時,一個字符串或字節(jié)類對象可以用于任一類型的地址。

    在 3.3 版更改: 之前,AF_UNIX 套接字路徑被假設(shè)使用 UTF-8 編碼。

    在 3.5 版更改: 現(xiàn)在接受可寫的 字節(jié)類對象。

  • 一對 (host, port) 被用作 AF_INET 地址族,其中 host 是一個表示互聯(lián)網(wǎng)域名標(biāo)記形式的主機(jī)名例如 'daring.cwi.nl' 或者 IPv4 地址例如 '100.50.200.5' 的字符串,而 port 是一個整數(shù)值。

    • 對于 IPv4 地址,有兩種可接受的特殊形式被用來代替一個主機(jī)地址: '' 代表 INADDR_ANY,用來綁定到所有接口;字符串 '<broadcast>' 代表 INADDR_BROADCAST。此行為不兼容 IPv6,因此,如果你的 Python 程序打算支持 IPv6,則可能需要避開這些。

  • 對于 AF_INET6 地址族,使用一個四元組 (host, port, flowinfo, scope_id),其中 flowinfoscope_id 代表了 C 庫 struct sockaddr_in6 中的 sin6_flowinfosin6_scope_id 成員。對于 socket 模塊中的方法, flowinfoscope_id 可以被省略,只為了向后兼容。注意,省略 scope_id 可能會導(dǎo)致操作帶有領(lǐng)域 (Scope) 的 IPv6 地址時出錯。

    在 3.7 版更改: 對于多播地址(其 scope_id 起作用),地址 中可以不包含 %scope_id (或 zone id )部分,這部分是多余的,可以放心省略(推薦)。

  • AF_NETLINK 套接字由一對 (pid, groups) 表示。

  • 指定 AF_TIPC 地址族可以使用僅 Linux 支持的 TIPC 協(xié)議。TIPC 是一種開放的、非基于 IP 的網(wǎng)絡(luò)協(xié)議,旨在用于集群計算環(huán)境。其地址用元組表示,其中的字段取決于地址類型。一般元組形式為 (addr_type, v1, v2, v3 [, scope]),其中:

    • addr_typeTIPC_ADDR_NAMESEQ、TIPC_ADDR_NAMETIPC_ADDR_ID 中的一個。

    • scopeTIPC_ZONE_SCOPE、TIPC_CLUSTER_SCOPETIPC_NODE_SCOPE 中的一個。

    • 如果 addr_typeTIPC_ADDR_NAME,那么 v1 是服務(wù)器類型,v2 是端口標(biāo)識符,v3 應(yīng)為 0。

      如果 addr_typeTIPC_ADDR_NAMESEQ,那么 v1 是服務(wù)器類型,v2 是端口號下限,而 v3 是端口號上限。

      如果 addr_typeTIPC_ADDR_ID,那么 v1 是節(jié)點 (node),v2 是 ref,v3 應(yīng)為 0。

  • AF_CAN 地址族使用元組 (interface, ),其中 interface 是表示網(wǎng)絡(luò)接口名稱的字符串,如 'can0'。網(wǎng)絡(luò)接口名 '' 可以用于接收本族所有網(wǎng)絡(luò)接口的數(shù)據(jù)包。

    • CAN_ISOTP 協(xié)議接受一個元組 (interface, rx_addr, tx_addr),其中兩個額外參數(shù)都是無符號長整數(shù),都表示 CAN 標(biāo)識符(標(biāo)準(zhǔn)或擴(kuò)展標(biāo)識符)。

    • CAN_J1939 協(xié)議接受一個元組 (interface, name, pgn, addr),其中額外參數(shù)有:表示 ECU 名稱的 64 位無符號整數(shù),表示參數(shù)組號 (Parameter Group Number, PGN) 的 32 位無符號整數(shù),以及表示地址的 8 位整數(shù)。

  • PF_SYSTEM 協(xié)議簇的 SYSPROTO_CONTROL 協(xié)議接受一個字符串或元組 (id, unit)。其中字符串是內(nèi)核控件的名稱,該控件使用動態(tài)分配的 ID。而如果 ID 和內(nèi)核控件的單元 (unit) 編號都已知,或使用了已注冊的 ID,可以采用元組。

    3.3 新版功能.

  • AF_BLUETOOTH 支持以下協(xié)議和地址格式:

    • BTPROTO_L2CAP 接受 (bdaddr, psm),其中 bdaddr 為字符串格式的藍(lán)牙地址,psm 是一個整數(shù)。

    • BTPROTO_RFCOMM 接受 (bdaddr, channel),其中 bdaddr 為字符串格式的藍(lán)牙地址,channel 是一個整數(shù)。

    • BTPROTO_HCI 接受 (device_id,),其中 device_id 為整數(shù)或字符串,它表示接口對應(yīng)的藍(lán)牙地址(具體取決于你的系統(tǒng),NetBSD 和 DragonFlyBSD 需要藍(lán)牙地址字符串,其他系統(tǒng)需要整數(shù))。

      在 3.2 版更改: 添加了對 NetBSD 和 DragonFlyBSD 的支持。

    • BTPROTO_SCO 接受 bdaddr,其中 bdaddrbytes 對象,其中含有字符串格式的藍(lán)牙地址(如 b'12:23:34:45:56:67' ),F(xiàn)reeBSD 不支持此協(xié)議。

  • AF_ALG 是一個僅 Linux 可用的、基于套接字的接口,用于連接內(nèi)核加密算法。算法套接字可用包括 2 至 4 個元素的元組來配置 (type, name [, feat [, mask]]),其中:

    • type 是表示算法類型的字符串,如 aead、hashskcipherrng。

    • name 是表示算法類型和操作模式的字符串,如 sha256、hmac(sha256)、cbc(aes)drbg_nopr_ctr_aes256。

    • featmask 是無符號 32 位整數(shù)。

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

    3.6 新版功能.

  • AF_VSOCK 用于支持虛擬機(jī)與宿主機(jī)之間的通訊。該套接字用 (CID, port) 元組表示,其中 Context ID (CID) 和 port 都是整數(shù)。

    Availability: Linux >= 4.8 QEMU >= 2.8 ESX >= 4.0 ESX Workstation >= 6.5.

    3.7 新版功能.

  • AF_PACKET 是一個底層接口,直接連接至網(wǎng)卡。數(shù)據(jù)包使用元組 (ifname, proto[, pkttype[, hatype[, addr]]]) 表示,其中:

    • ifname - 指定設(shè)備名稱的字符串。

    • proto - 一個用網(wǎng)絡(luò)字節(jié)序表示的整數(shù),指定以太網(wǎng)協(xié)議版本號。

    • pkttype - 指定數(shù)據(jù)包類型的整數(shù)(可選):

      • PACKET_HOST (默認(rèn)) - 尋址到本地主機(jī)的數(shù)據(jù)包。

      • PACKET_BROADCAST - 物理層廣播的數(shù)據(jù)包。

      • PACKET_MULTICAST - Packet sent to a physical-layer multicast address.

      • PACKET_OTHERHOST - 被(處于混雜模式的)網(wǎng)卡驅(qū)動捕獲的、發(fā)送到其他主機(jī)的數(shù)據(jù)包。

      • PACKET_OUTGOING - 來自本地主機(jī)的、回環(huán)到一個套接字的數(shù)據(jù)包。

    • hatype - 可選整數(shù),指定 ARP 硬件地址類型。

    • addr - 可選的類字節(jié)串對象,用于指定硬件物理地址,其解釋取決于各設(shè)備。

    Availability: Linux >= 2.2.

  • AF_QIPCRTR 是一個僅 Linux 可用的、基于套接字的接口,用于與高通平臺中協(xié)處理器上運行的服務(wù)進(jìn)行通信。該地址簇用一個 (node, port) 元組表示,其中 nodeport 為非負(fù)整數(shù)。

    Availability: Linux >= 4.7.

    3.8 新版功能.

  • IPPROTO_UDPLITE 是一種 UDP 的變體,允許指定數(shù)據(jù)包的哪一部分計算入校驗碼內(nèi)。它添加了兩個可以修改的套接字選項。self.setsockopt(IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV, length) 修改傳出數(shù)據(jù)包的哪一部分計算入校驗碼內(nèi),而 self.setsockopt(IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV, length) 將過濾掉計算入校驗碼的數(shù)據(jù)太少的數(shù)據(jù)包。在這兩種情況下,length 都應(yīng)在 range(8, 2**16, 8) 范圍內(nèi)。

    對于 IPv4,應(yīng)使用 socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE) 來構(gòu)造這樣的套接字;對于 IPv6,應(yīng)使用 socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE) 來構(gòu)造這樣的套接字。

    Availability: Linux >= 2.6.20, FreeBSD >= 10.1-RELEASE

    3.9 新版功能.

  • AF_HYPERV is a Windows-only socket based interface for communicating with Hyper-V hosts and guests. The address family is represented as a (vm_id, service_id) tuple where the vm_id and service_id are UUID strings.

    The vm_id is the virtual machine identifier or a set of known VMID values if the target is not a specific virtual machine. Known VMID constants defined on socket are:

    • HV_GUID_ZERO

    • HV_GUID_BROADCAST

    • HV_GUID_WILDCARD - Used to bind on itself and accept connections from all partitions.

    • HV_GUID_CHILDREN - Used to bind on itself and accept connection from child partitions.

    • HV_GUID_LOOPBACK - Used as a target to itself.

    • HV_GUID_PARENT - When used as a bind accepts connection from the parent partition. When used as an address target it will connect to the parent parition.

    The service_id is the service identifier of the registered service.

    3.12 新版功能.

如果你在 IPv4/v6 套接字地址的 host 部分中使用了一個主機(jī)名,此程序可能會表現(xiàn)不確定行為,因為 Python 使用 DNS 解析返回的第一個地址。套接字地址在實際的 IPv4/v6 中以不同方式解析,根據(jù) DNS 解析和/或 host 配置。為了確定行為,在 host 部分中使用數(shù)字的地址。

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 OSError or one of its subclasses.

可以用 setblocking() 設(shè)置非阻塞模式。一個基于超時的 generalization 通過 settimeout() 支持。

模塊內(nèi)容?

socket 模塊包含下列元素。

異常?

exception socket.error?

一個被棄用的 OSError 的別名。

在 3.3 版更改: 根據(jù) PEP 3151,這個類是 OSError 的別名。

exception socket.herror?

OSError 的子類,本異常通常表示與地址相關(guān)的錯誤,比如那些在 POSIX C API 中使用了 h_errno 的函數(shù),包括 gethostbyname_ex()gethostbyaddr()。附帶的值是一對 (h_errno, string),代表庫調(diào)用返回的錯誤。h_errno 是一個數(shù)字,而 string 表示 h_errno 的描述,它們由 C 函數(shù) hstrerror() 返回。

在 3.3 版更改: 此類是 OSError 的子類。

exception socket.gaierror?

OSError 的子類,本異常來自 getaddrinfo()getnameinfo(),表示與地址相關(guān)的錯誤。附帶的值是一對 (error, string),代表庫調(diào)用返回的錯誤。string 表示 error 的描述,它由 C 函數(shù) gai_strerror() 返回。數(shù)字值 error 與本模塊中定義的 EAI_* 常量之一匹配。

在 3.3 版更改: 此類是 OSError 的子類。

exception socket.timeout?

TimeoutError 的已被棄用的別名。

OSError 的子類,當(dāng)套接字發(fā)生超時,且事先已調(diào)用過 settimeout() (或隱式地通過 setdefaulttimeout() )啟用了超時,則會拋出此異常。附帶的值是一個字符串,其值總是 "timed out"。

在 3.3 版更改: 此類是 OSError 的子類。

在 3.10 版更改: 這個類是 TimeoutError 的別名。

常量?

AF_* 和 SOCK_* 常量現(xiàn)在都在 AddressFamilySocketKind 這兩個 IntEnum 集合內(nèi)。

3.4 新版功能.

socket.AF_UNIX?
socket.AF_INET?
socket.AF_INET6?

這些常量表示地址(和協(xié)議)簇,用于 socket() 的第一個參數(shù)。如果 AF_UNIX 常量未定義,即表示不支持該協(xié)議。不同系統(tǒng)可能會有更多其他常量可用。

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

這些常量表示套接字類型,用于 socket() 的第二個參數(shù)。不同系統(tǒng)可能會有更多其他常量可用。(一般只有 SOCK_STREAMSOCK_DGRAM 可用)

socket.SOCK_CLOEXEC?
socket.SOCK_NONBLOCK?

這兩個常量(如果已定義)可以與上述套接字類型結(jié)合使用,允許你設(shè)置這些原子性相關(guān)的 flags (從而避免可能的競爭條件和單獨調(diào)用的需要)。

可用性: Linux >= 2.6.27。

3.2 新版功能.

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

此列表內(nèi)的許多常量,記載在 Unix 文檔中的套接字和/或 IP 協(xié)議部分,同時也定義在本 socket 模塊中。它們通常用于套接字對象的 setsockopt()getsockopt() 方法的參數(shù)中。在大多數(shù)情況下,僅那些在 Unix 頭文件中有定義的符號會在本模塊中定義,部分符號提供了默認(rèn)值。

在 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 版更改: Added TCP_CONNECTION_INFO. On MacOS this constant can be used in the same way that TCP_INFO is used on Linux and BSD.

在 3.12 版更改: Added SO_RTABLE and SO_USER_COOKIE. On OpenBSD and FreeBSD respectively those constants can be used in the same way that SO_MARK is used on Linux.

socket.AF_CAN?
socket.PF_CAN?
SOL_CAN_*
CAN_*

此列表內(nèi)的許多常量,記載在 Linux 文檔中,同時也定義在本 socket 模塊中。

Availability: Linux >= 2.6.25, NetBSD >= 8.

3.3 新版功能.

在 3.11 版更改: NetBSD support was added.

socket.CAN_BCM?
CAN_BCM_*

CAN 協(xié)議簇內(nèi)的 CAN_BCM 是廣播管理器(Bbroadcast Manager -- BCM)協(xié)議,廣播管理器常量在 Linux 文檔中有所記載,在本 socket 模塊中也有定義。

可用性: Linux >= 2.6.25。

備注

CAN_BCM_CAN_FD_FRAME 旗標(biāo)僅在 Linux >= 4.8 時可用。

3.4 新版功能.

socket.CAN_RAW_FD_FRAMES?

在 CAN_RAW 套接字中啟用 CAN FD 支持,默認(rèn)是禁用的。它使應(yīng)用程序可以發(fā)送 CAN 和 CAN FD 幀。但是,從套接字讀取時,也必須同時接受 CAN 和 CAN FD 幀。

此常量在 Linux 文檔中有所記載。

可用性: Linux >= 3.6。

3.5 新版功能.

socket.CAN_RAW_JOIN_FILTERS?

加入已應(yīng)用的 CAN 過濾器,這樣只有與所有 CAN 過濾器匹配的 CAN 幀才能傳遞到用戶空間。

此常量在 Linux 文檔中有所記載。

可用性: Linux >= 4.1。

3.9 新版功能.

socket.CAN_ISOTP?

CAN 協(xié)議簇中的 CAN_ISOTP 就是 ISO-TP (ISO 15765-2) 協(xié)議。ISO-TP 常量在 Linux 文檔中有所記載。

可用性: Linux >= 2.6.25。

3.7 新版功能.

socket.CAN_J1939?

CAN 協(xié)議族中的 CAN_J1939 即 SAE J1939 協(xié)議。 J1939 常量記錄在 Linux 文檔中。

可用性: Linux >= 5.4。

3.9 新版功能.

socket.AF_PACKET?
socket.PF_PACKET?
PACKET_*

此列表內(nèi)的許多常量,記載在 Linux 文檔中,同時也定義在本 socket 模塊中。

可用性: Linux >= 2.2。

socket.AF_RDS?
socket.PF_RDS?
socket.SOL_RDS?
RDS_*

此列表內(nèi)的許多常量,記載在 Linux 文檔中,同時也定義在本 socket 模塊中。

可用性: Linux >= 2.6.30。

3.3 新版功能.

socket.SIO_RCVALL?
socket.SIO_KEEPALIVE_VALS?
socket.SIO_LOOPBACK_FAST_PATH?
RCVALL_*

Windows 的 WSAIoctl() 的常量。這些常量用于套接字對象的 ioctl() 方法的參數(shù)。

在 3.6 版更改: 添加了 SIO_LOOPBACK_FAST_PATH。

TIPC_*

TIPC 相關(guān)常量,與 C socket API 導(dǎo)出的常量一致。更多信息請參閱 TIPC 文檔。

socket.AF_ALG?
socket.SOL_ALG?
ALG_*

用于 Linux 內(nèi)核加密算法的常量。

可用性: Linux >= 2.6.38。

3.6 新版功能.

socket.AF_VSOCK?
socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID?
VMADDR*
SO_VM*

用于 Linux 宿主機(jī)/虛擬機(jī)通訊的常量。

可用性: Linux >= 4.8。

3.7 新版功能.

Availability: BSD, macOS.

3.4 新版功能.

socket.has_ipv6?

本常量為一個布爾值,該值指示當(dāng)前平臺是否支持 IPv6。

socket.BDADDR_ANY?
socket.BDADDR_LOCAL?

這些是字符串常量,包含藍(lán)牙地址,這些地址具有特殊含義。例如,當(dāng)用 BTPROTO_RFCOMM 指定綁定套接字時, BDADDR_ANY 表示“任何地址”。

socket.HCI_FILTER?
socket.HCI_TIME_STAMP?
socket.HCI_DATA_DIR?

BTPROTO_HCI 一起使用。 HCI_FILTER 在 NetBSD 或 DragonFlyBSD 上不可用。 HCI_TIME_STAMPHCI_DATA_DIR 在 FreeBSD、NetBSD 或 DragonFlyBSD 上不可用。

socket.AF_QIPCRTR?

高通 IPC 路由協(xié)議的常數(shù),用于與提供遠(yuǎn)程處理器的服務(wù)進(jìn)行通信。

可用性: Linux >= 4.7。

socket.SCM_CREDS2?
socket.LOCAL_CREDS?
socket.LOCAL_CREDS_PERSISTENT?

LOCAL_CREDS and LOCAL_CREDS_PERSISTENT can be used with SOCK_DGRAM, SOCK_STREAM sockets, equivalent to Linux/DragonFlyBSD SO_PASSCRED, while LOCAL_CREDS sends the credentials at first read, LOCAL_CREDS_PERSISTENT sends for each read, SCM_CREDS2 must be then used for the latter for the message type.

3.11 新版功能.

Availability: FreeBSD.

socket.SO_INCOMING_CPU?

Constant to optimize CPU locality, to be used in conjunction with SO_REUSEPORT.

3.11 新版功能.

Availability: Linux >= 3.9

socket.AF_HYPERV?
socket.HV_PROTOCOL_RAW?
socket.HVSOCKET_CONNECT_TIMEOUT?
socket.HVSOCKET_CONNECT_TIMEOUT_MAX?
socket.HVSOCKET_CONTAINER_PASSTHRU?
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_LOOPBACK

Constants for Windows Hyper-V sockets for host/guest communications.

可用性: Windows。

3.12 新版功能.

函數(shù)?

創(chuàng)建套接字?

下列函數(shù)都能創(chuàng)建 套接字對象.

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

使用給定的地址族、套接字類型和協(xié)議號創(chuàng)建一個新的套接字。 地址族應(yīng)為 AF_INET (默認(rèn)值), AF_INET6, AF_UNIX, AF_CAN, AF_PACKETAF_RDS 之一。 套接字類型應(yīng)為 SOCK_STREAM (默認(rèn)值), SOCK_DGRAM, SOCK_RAW 或其他可能的 SOCK_ 常量之一。 協(xié)議號通常為零并且可以省略,或在協(xié)議族為 AF_CAN 的情況下,協(xié)議應(yīng)為 CAN_RAW, CAN_BCM, CAN_ISOTPCAN_J1939 之一。

如果指定了 fileno,那么將從這一指定的文件描述符中自動檢測 family、typeproto 的值。如果調(diào)用本函數(shù)時顯式指定了 family、typeproto 參數(shù),可以覆蓋自動檢測的值。這只會影響 Python 表示諸如 socket.getpeername() 一類函數(shù)的返回值的方式,而不影響實際的操作系統(tǒng)資源。與 socket.fromfd() 不同,fileno 將返回原先的套接字,而不是復(fù)制出新的套接字。這有助于在分離的套接字上調(diào)用 socket.close() 來關(guān)閉它。

新創(chuàng)建的套接字是 不可繼承的。

引發(fā)一個 審計事件 socket.__new__ 附帶參數(shù) self、family、typeprotocol。

在 3.3 版更改: 添加了 AF_CAN 簇。添加了 AF_RDS 簇。

在 3.4 版更改: 添加了 CAN_BCM 協(xié)議。

在 3.4 版更改: 返回的套接字現(xiàn)在是不可繼承的。

在 3.7 版更改: 添加了 CAN_ISOTP 協(xié)議。

在 3.7 版更改: 當(dāng)將 SOCK_NONBLOCKSOCK_CLOEXEC 標(biāo)志位應(yīng)用于 type 上時,它們會被清除,且 socket.type 反映不出它們。但它們?nèi)詫鬟f給底層系統(tǒng)的 socket() 調(diào)用。因此,

sock = socket.socket(
    socket.AF_INET,
    socket.SOCK_STREAM | socket.SOCK_NONBLOCK)

仍將在支持 SOCK_NONBLOCK 的系統(tǒng)上創(chuàng)建一個非阻塞的套接字,但是 sock.type 會被置為 socket.SOCK_STREAM

在 3.9 版更改: 添加了 CAN_J1939 協(xié)議。

在 3.10 版更改: 添加了 IPPROTO_MPTCP 協(xié)議。

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

構(gòu)建一對已連接的套接字對象,使用給定的地址簇、套接字類型和協(xié)議號。地址簇、套接字類型和協(xié)議號與上述 socket() 函數(shù)相同。默認(rèn)地址簇為 AF_UNIX (需要當(dāng)前平臺支持,不支持則默認(rèn)為 AF_INET )。

新創(chuàng)建的套接字都是 不可繼承的

在 3.2 版更改: 現(xiàn)在,返回的套接字對象支持全部套接字 API,而不是全部 API 的一個子集。

在 3.4 版更改: 返回的套接字現(xiàn)在都是不可繼承的。

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

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

連接到一個在互聯(lián)網(wǎng) address (以 (host, port) 2 元組表示) 上偵聽的 TCP 服務(wù),并返回套接字對象。 這是一個相比 socket.connect() 層級更高的函數(shù):如果 host 是非數(shù)字的主機(jī)名,它將嘗試將其解析為 AF_INETAF_INET6,然后依次嘗試連接到所有可能的地址直到連接成功。 這使編寫兼容 IPv4 和 IPv6 的客戶端變得很容易。

傳入可選參數(shù) timeout 可以在套接字實例上設(shè)置超時(在嘗試連接前)。如果未提供 timeout,則使用由 getdefaulttimeout() 返回的全局默認(rèn)超時設(shè)置。

如果提供了 source_address,它必須為二元組 (host, port),以便套接字在連接之前綁定為其源地址。如果 host 或 port 分別為 '' 或 0,則使用操作系統(tǒng)默認(rèn)行為。

When a connection cannot be created, an exception is raised. By default, it is the exception from the last address in the list. If all_errors is True, it is an ExceptionGroup containing the errors of all attempts.

在 3.2 版更改: 添加了*source_address* 參數(shù)

在 3.11 版更改: all_errors was added.

socket.create_server(address, *, family=AF_INET, backlog=None, reuse_port=False, dualstack_ipv6=False)?

Convenience function which creates a TCP socket bound to address (a 2-tuple (host, port)) and returns the socket object.

family 應(yīng)設(shè)置為 AF_INETAF_INET6。backlog 是傳遞給 socket.listen() 的隊列大小,當(dāng)它為 0 則表示默認(rèn)的合理值。reuse_port 表示是否設(shè)置 SO_REUSEPORT 套接字選項。

如果 dualstack_ipv6 為 true 且平臺支持,則套接字能接受 IPv4 和 IPv6 連接,否則將拋出 ValueError 異常。大多數(shù) POSIX 平臺和 Windows 應(yīng)該支持此功能。啟用此功能后,socket.getpeername() 在進(jìn)行 IPv4 連接時返回的地址將是一個(映射到 IPv4 的)IPv6 地址。在默認(rèn)啟用該功能的平臺上(如 Linux),如果 dualstack_ipv6 為 false,即顯式禁用此功能。該參數(shù)可以與 has_dualstack_ipv6() 結(jié)合使用:

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 平臺上,設(shè)置 SO_REUSEADDR 套接字選項是為了立即重用以前綁定在同一 address 上并保持 TIME_WAIT 狀態(tài)的套接字。

3.8 新版功能.

socket.has_dualstack_ipv6()?

如果平臺支持創(chuàng)建 IPv4 和 IPv6 連接都可以處理的 TCP 套接字,則返回 True

3.8 新版功能.

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

復(fù)制文件描述符 fd (一個由文件對象的 fileno() 方法返回的整數(shù)),然后從結(jié)果中構(gòu)建一個套接字對象。地址簇、套接字類型和協(xié)議號與上述 socket() 函數(shù)相同。文件描述符應(yīng)指向一個套接字,但不會專門去檢查——如果文件描述符是無效的,則對該對象的后續(xù)操作可能會失敗。本函數(shù)很少用到,但是在將套接字作為標(biāo)準(zhǔn)輸入或輸出傳遞給程序(如 Unix inet 守護(hù)程序啟動的服務(wù)器)時,可以使用本函數(shù)獲取或設(shè)置套接字選項。套接字將處于阻塞模式。

新創(chuàng)建的套接字是 不可繼承的。

在 3.4 版更改: 返回的套接字現(xiàn)在是不可繼承的。

socket.fromshare(data)?

根據(jù) socket.share() 方法獲得的數(shù)據(jù)實例化套接字。套接字將處于阻塞模式。

可用性: Windows。

3.3 新版功能.

socket.SocketType?

這是一個 Python 類型對象,表示套接字對象的類型。它等同于 type(socket(...))

其他功能?

socket 模塊還提供多種網(wǎng)絡(luò)相關(guān)服務(wù):

socket.close(fd)?

關(guān)閉一個套接字文件描述符。它類似于 os.close(),但專用于套接字。在某些平臺上(特別是在 Windows 上),os.close() 對套接字文件描述符無效。

3.7 新版功能.

socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)?

host/port 參數(shù)轉(zhuǎn)換為 5 元組的序列,其中包含創(chuàng)建(連接到某服務(wù)的)套接字所需的所有參數(shù)。host 是域名,是字符串格式的 IPv4/v6 地址或 None。port 是字符串格式的服務(wù)名稱,如 'http' 、端口號(數(shù)字)或 None。傳入 None 作為 hostport 的值,相當(dāng)于將 NULL 傳遞給底層 C API。

可以指定 familytypeproto 參數(shù),以縮小返回的地址列表。向這些參數(shù)分別傳入 0 表示保留全部結(jié)果范圍。flags 參數(shù)可以是 AI_* 常量中的一個或多個,它會影響結(jié)果的計算和返回。例如,AI_NUMERICHOST 會禁用域名解析,此時如果 host 是域名,則會拋出錯誤。

本函數(shù)返回一個列表,其中的 5 元組具有以下結(jié)構(gòu):

(family, type, proto, canonname, sockaddr)

在這些元組中,family, type, proto 都是整數(shù)且其作用是被傳入 socket() 函數(shù)。 如果 AI_CANONNAMEflags 參數(shù)的一部分則 canonname 將是表示 host 規(guī)范名稱的字符串;否則 canonname 將為空。 sockaddr 是一個描述套接字地址的元組,其具體格式取決于返回的 family (對于 AF_INET(address, port) 2 元組,對于 AF_INET6 則為 (address, port, flowinfo, scope_id) 4 元組),其作用是被傳入 socket.connect() 方法。

引發(fā)一個 審計事件 socket.getaddrinfo 附帶參數(shù) hostport、familytype、protocol。

下面的示例獲取了 TCP 連接地址信息,假設(shè)該連接通過 80 端口連接至 example.org (如果系統(tǒng)未啟用 IPv6,則結(jié)果可能會不同):

>>>
>>> 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 版更改: 現(xiàn)在可以使用關(guān)鍵字參數(shù)的形式來傳遞參數(shù)。

在 3.7 版更改: 對于 IPv6 多播地址,表示地址的字符串將不包含 %scope_id 部分。

socket.getfqdn([name])?

Return a fully qualified domain name for name. If name is omitted or empty, it is interpreted as the local host. To find the fully qualified name, the hostname returned by gethostbyaddr() is checked, followed by aliases for the host, if available. The first name which includes a period is selected. In case no fully qualified domain name is available and name was provided, it is returned unchanged. If name was empty or equal to '0.0.0.0', the hostname from gethostname() is returned.

socket.gethostbyname(hostname)?

將主機(jī)名轉(zhuǎn)換為 IPv4 地址格式。IPv4 地址以字符串格式返回,如 '100.50.200.5'。如果主機(jī)名本身是 IPv4 地址,則原樣返回。更完整的接口請參考 gethostbyname_ex()gethostbyname() 不支持 IPv6 名稱解析,應(yīng)使用 getaddrinfo() 來支持 IPv4/v6 雙協(xié)議棧。

引發(fā)一個 審計事件 socket.gethostbyname,附帶參數(shù) hostname。

socket.gethostbyname_ex(hostname)?

Translate a host name to IPv4 address format, extended interface. Return a triple (hostname, aliaslist, ipaddrlist) where hostname is the host's primary host name, aliaslist is a (possibly empty) list of alternative host names for the same address, and ipaddrlist is a list of IPv4 addresses for the same interface on the same host (often but not always a single address). gethostbyname_ex() does not support IPv6 name resolution, and getaddrinfo() should be used instead for IPv4/v6 dual stack support.

引發(fā)一個 審計事件 socket.gethostbyname,附帶參數(shù) hostname。

socket.gethostname()?

返回一個字符串,包含當(dāng)前正在運行 Python 解釋器的機(jī)器的主機(jī)名。

引發(fā)一個 審計事件 socket.gethostname,沒有附帶參數(shù)。

注意: gethostname() 并不總是返回全限定域名,必要的話請使用 getfqdn()

socket.gethostbyaddr(ip_address)?

返回三元組 (hostname, aliaslist, ipaddrlist),其中 hostname 是響應(yīng)給定 ip_address 的主要主機(jī)名,aliaslist 是相同地址的其他可用主機(jī)名的列表(可能為空),而 ipaddrlist 是 IPv4/v6 地址列表,包含相同主機(jī)名、相同接口的不同地址(很可能僅包含一個地址)。要查詢?nèi)薅ㄓ蛎?,請使用函?shù) getfqdn()。gethostbyaddr() 支持 IPv4 和 IPv6。

引發(fā)一個 審計事件 socket.gethostbyaddr,附帶參數(shù) ip_address。

socket.getnameinfo(sockaddr, flags)?

將套接字地址 sockaddr 轉(zhuǎn)換為二元組 (host, port)。host 的形式可能是全限定域名,或是由數(shù)字表示的地址,具體取決于 flags 的設(shè)置。同樣,port 可以包含字符串格式的端口名稱或數(shù)字格式的端口號。

對于 IPv6 地址,如果 sockaddr 包含有意義的 scope_id,則 %scope_id 會被附加到主機(jī)部分。 這種情況通常發(fā)生在多播地址上。

關(guān)于 flags 的更多信息可參閱 getnameinfo(3)。

引發(fā)一個 審計事件 socket.getnameinfo,附帶參數(shù) sockaddr。

socket.getprotobyname(protocolname)?

將一個互聯(lián)網(wǎng)協(xié)議名稱 (如 'icmp') 轉(zhuǎn)換為能被作為 (可選的) 第三個參數(shù)傳給 socket() 函數(shù)的常量。 這通常僅對以 "raw" 模式 (SOCK_RAW) 打開的套接字來說是必要的;對于正常的套接字模式,當(dāng)該協(xié)議名稱被省略或為零時會自動選擇正確的協(xié)議。

socket.getservbyname(servicename[, protocolname])?

將一個互聯(lián)網(wǎng)服務(wù)名稱和協(xié)議名稱轉(zhuǎn)換為該服務(wù)的端口號。 如果給出了可選的協(xié)議名稱,它應(yīng)為 'tcp''udp',否則將匹配任意的協(xié)議。

引發(fā)一個 審計事件 socket.getservbyname,附帶參數(shù) servicenameprotocolname。

socket.getservbyport(port[, protocolname])?

將一個互聯(lián)網(wǎng)端口號和協(xié)議名稱轉(zhuǎn)換為該服務(wù)的服務(wù)名稱。 如果給出了可選的協(xié)議名稱,它應(yīng)為 'tcp''udp',否則將匹配任意的協(xié)議。

引發(fā)一個 審計事件 socket.getservbyport,附帶參數(shù) port、protocolname。

socket.ntohl(x)?

將 32 位正整數(shù)從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機(jī)字節(jié)序。在主機(jī)字節(jié)序與網(wǎng)絡(luò)字節(jié)序相同的計算機(jī)上,這是一個空操作。字節(jié)序不同將執(zhí)行 4 字節(jié)交換操作。

socket.ntohs(x)?

將 16 位正整數(shù)從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機(jī)字節(jié)序。在主機(jī)字節(jié)序與網(wǎng)絡(luò)字節(jié)序相同的計算機(jī)上,這是一個空操作。字節(jié)序不同將執(zhí)行 2 字節(jié)交換操作。

在 3.10 版更改: 如果 x 不能轉(zhuǎn)為 16 位無符號整數(shù)則會引發(fā) OverflowError。

socket.htonl(x)?

將 32 位正整數(shù)從主機(jī)字節(jié)序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序。在主機(jī)字節(jié)序與網(wǎng)絡(luò)字節(jié)序相同的計算機(jī)上,這是一個空操作。字節(jié)序不同將執(zhí)行 4 字節(jié)交換操作。

socket.htons(x)?

將 16 位正整數(shù)從主機(jī)字節(jié)序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序。在主機(jī)字節(jié)序與網(wǎng)絡(luò)字節(jié)序相同的計算機(jī)上,這是一個空操作。字節(jié)序不同將執(zhí)行 2 字節(jié)交換操作。

在 3.10 版更改: 如果 x 不能轉(zhuǎn)為 16 位無符號整數(shù)則會引發(fā) OverflowError

socket.inet_aton(ip_string)?

將 IPv4 地址從點分十進(jìn)制字符串格式(如 '123.45.67.89' )轉(zhuǎn)換為 32 位壓縮二進(jìn)制格式,轉(zhuǎn)換后為字節(jié)對象,長度為四個字符。與那些使用標(biāo)準(zhǔn) C 庫,且需要 struct in_addr 類型的對象的程序交換信息時,此功能很有用。 該類型即此函數(shù)返回的 32 位壓縮二進(jìn)制的 C 類型。

inet_aton() 也接受句點數(shù)少于三的字符串,詳情請參閱 Unix 手冊 inet(3)。

如果傳入本函數(shù)的 IPv4 地址字符串無效,則拋出 OSError。注意,具體什么樣的地址有效取決于 inet_aton() 的底層 C 實現(xiàn)。

inet_aton() 不支持 IPv6,在 IPv4/v6 雙協(xié)議棧下應(yīng)使用 inet_pton() 來代替。

socket.inet_ntoa(packed_ip)?

將 32 位壓縮 IPv4 地址(一個 類字節(jié)對象,長 4 個字節(jié))轉(zhuǎn)換為標(biāo)準(zhǔn)的點分十進(jìn)制字符串形式(如 '123.45.67.89' )。與那些使用標(biāo)準(zhǔn) C 庫,且需要 struct in_addr 類型的對象的程序交換信息時,本函數(shù)很有用。 該類型即是本函數(shù)參數(shù)中的 32 位壓縮二進(jìn)制數(shù)據(jù)的 C 類型。

如果傳入本函數(shù)的字節(jié)序列長度不是 4 個字節(jié),則拋出 OSErrorinet_ntoa() 不支持 IPv6,在 IPv4/v6 雙協(xié)議棧下應(yīng)使用 inet_ntop() 來代替。

在 3.5 版更改: 現(xiàn)在接受可寫的 字節(jié)類對象。

socket.inet_pton(address_family, ip_string)?

將特定地址簇的 IP 地址(字符串)轉(zhuǎn)換為壓縮二進(jìn)制格式。當(dāng)庫或網(wǎng)絡(luò)協(xié)議需要接受 struct in_addr 類型的對象(類似 inet_aton() )或 struct in6_addr 類型的對象時,inet_pton() 很有用。

目前 address_family 支持 AF_INETAF_INET6。如果 IP 地址字符串 ip_string 無效,則拋出 OSError。注意,具體什么地址有效取決于 address_family 的值和 inet_pton() 的底層實現(xiàn)。

可用性: Unix(可能非所有平臺都可用)、Windows。

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

socket.inet_ntop(address_family, packed_ip)?

將壓縮 IP 地址(一個 類字節(jié)對象,數(shù)個字節(jié)長)轉(zhuǎn)換為標(biāo)準(zhǔn)的、特定地址簇的字符串形式(如 '7.10.0.5''5aef:2b::8' )。當(dāng)庫或網(wǎng)絡(luò)協(xié)議返回 struct in_addr 類型的對象(類似 inet_ntoa() )或 struct in6_addr 類型的對象時,inet_ntop() 很有用。

目前 address_family 支持 AF_INETAF_INET6。如果字節(jié)對象 packed_ip 與指定的地址簇長度不符,則拋出 ValueError。針對 inet_ntop() 調(diào)用的錯誤則拋出 OSError。

可用性: Unix(可能非所有平臺都可用)、Windows。

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

在 3.5 版更改: 現(xiàn)在接受可寫的 字節(jié)類對象。

socket.CMSG_LEN(length)?

返回給定 length 所關(guān)聯(lián)數(shù)據(jù)的輔助數(shù)據(jù)項的總長度(不帶尾部填充)。此值通常用作 recvmsg() 接收一個輔助數(shù)據(jù)項的緩沖區(qū)大小,但是 RFC 3542 要求可移植應(yīng)用程序使用 CMSG_SPACE(),以此將尾部填充的空間計入,即使該項在緩沖區(qū)的最后。如果 length 超出允許范圍,則拋出 OverflowError。

可用性: 大多數(shù) Unix 平臺,其他平臺也可能可用。

3.3 新版功能.

socket.CMSG_SPACE(length)?

返回 recvmsg() 所需的緩沖區(qū)大小,以接收給定 length 所關(guān)聯(lián)數(shù)據(jù)的輔助數(shù)據(jù)項,帶有尾部填充。接收多個項目所需的緩沖區(qū)空間是關(guān)聯(lián)數(shù)據(jù)長度的 CMSG_SPACE() 值的總和。如果 length 超出允許范圍,則拋出 OverflowError

請注意,某些系統(tǒng)可能支持輔助數(shù)據(jù),但不提供本函數(shù)。還需注意,如果使用本函數(shù)的結(jié)果來設(shè)置緩沖區(qū)大小,可能無法精確限制可接收的輔助數(shù)據(jù)量,因為可能會有其他數(shù)據(jù)寫入尾部填充區(qū)域。

可用性: 大多數(shù) Unix 平臺,其他平臺也可能可用。

3.3 新版功能.

socket.getdefaulttimeout()?

返回用于新套接字對象的默認(rèn)超時(以秒為單位的浮點數(shù))。值 None 表示新套接字對象沒有超時。首次導(dǎo)入 socket 模塊時,默認(rèn)值為 None。

socket.setdefaulttimeout(timeout)?

設(shè)置用于新套接字對象的默認(rèn)超時(以秒為單位的浮點數(shù))。首次導(dǎo)入 socket 模塊時,默認(rèn)值為 None??赡艿娜≈导捌涓髯缘暮x請參閱 settimeout()

socket.sethostname(name)?

將計算機(jī)的主機(jī)名設(shè)置為 name。如果權(quán)限不足將拋出 OSError

引發(fā)一個 審計事件 socket.sethostname,附帶參數(shù) name

可用性: Unix。

3.3 新版功能.

socket.if_nameindex()?

返回一個列表,包含網(wǎng)絡(luò)接口(網(wǎng)卡)信息二元組(整數(shù)索引,名稱字符串)。系統(tǒng)調(diào)用失敗則拋出 OSError。

可用性: Unix, Windows。

3.3 新版功能.

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

備注

在 Windows 中網(wǎng)絡(luò)接口在不同上下文中具有不同的名稱(所有名稱見對應(yīng)示例):

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

  • 名稱: ethernet_32770

  • 友好名稱: vEthernet (nat)

  • 描述: Hyper-V Virtual Ethernet Adapter

此函數(shù)返回列表中第二種形式的名稱,在此示例中為 ethernet_32770。

socket.if_nametoindex(if_name)?

返回網(wǎng)絡(luò)接口名稱相對應(yīng)的索引號。如果沒有所給名稱的接口,則拋出 OSError。

可用性: Unix, Windows。

3.3 新版功能.

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

參見

"Interface name" 為 if_nameindex() 中所描述的名稱。

socket.if_indextoname(if_index)?

返回網(wǎng)絡(luò)接口索引號相對應(yīng)的接口名稱。如果沒有所給索引號的接口,則拋出 OSError。

可用性: Unix, Windows。

3.3 新版功能.

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

參見

"Interface name" 為 if_nameindex() 中所描述的名稱。

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

將文件描述符列表 fds 通過一個 AF_UNIX 套接字 sock 進(jìn)行發(fā)送。 fds 形參是由文件描述符構(gòu)成的序列。 請查看 sendmsg() 獲取這些形參的文檔。

可用性: 支持 sendmsg()SCM_RIGHTS 機(jī)制的 Unix 系統(tǒng)。

3.9 新版功能.

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

接收至多 maxfds 個來自 AF_UNIX 套接字 sock 的文件描述符。 返回 (msg, list(fds), flags, addr)。 請查看 recvmsg() 獲取有些形參的文檔。

可用性: 支持 recvmsg()SCM_RIGHTS 機(jī)制的 Unix 系統(tǒng)。

3.9 新版功能.

備注

位于文件描述符列表末尾的任何被截斷整數(shù)。

套接字對象?

套接字對象具有以下方法。除了 makefile(),其他都與套接字專用的 Unix 系統(tǒng)調(diào)用相對應(yīng)。

在 3.2 版更改: 添加了對 上下文管理器 協(xié)議的支持。退出上下文管理器與調(diào)用 close() 等效。

socket.accept()?

接受一個連接。此 socket 必須綁定到一個地址上并且監(jiān)聽連接。返回值是一個 (conn, address) 對,其中 conn 是一個 的套接字對象,用于在此連接上收發(fā)數(shù)據(jù),address 是連接另一端的套接字所綁定的地址。

新創(chuàng)建的套接字是 不可繼承的。

在 3.4 版更改: 該套接字現(xiàn)在是不可繼承的。

在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號處理程序沒有觸發(fā)異常,此方法現(xiàn)在會重試系統(tǒng)調(diào)用,而不是觸發(fā) InterruptedError 異常 (原因詳見 PEP 475)。

socket.bind(address)?

將套接字綁定到 address。套接字必須尚未綁定。( address 的格式取決于地址簇 —— 參見上文)

引發(fā)一個 審計事件 socket.bind,附帶參數(shù) self、address。

socket.close()?

將套接字標(biāo)記為關(guān)閉。當(dāng) makefile() 創(chuàng)建的所有文件對象都關(guān)閉時,底層系統(tǒng)資源(如文件描述符)也將關(guān)閉。一旦上述情況發(fā)生,將來對套接字對象的所有操作都會失敗。對端將接收不到任何數(shù)據(jù)(清空隊列數(shù)據(jù)后)。

垃圾回收時,套接字會自動關(guān)閉,但建議顯式 close() 它們,或在它們周圍使用 with 語句。

在 3.6 版更改: 現(xiàn)在,如果底層的 close() 調(diào)用出錯,會拋出 OSError。

備注

close() 釋放與連接相關(guān)聯(lián)的資源,但不一定立即關(guān)閉連接。如果需要及時關(guān)閉連接,請在調(diào)用 close() 之前調(diào)用 shutdown()。

socket.connect(address)?

連接到 address 處的遠(yuǎn)程套接字。( address 的格式取決于地址簇 —— 參見上文)

如果連接被信號中斷,則本方法將等待直至連接完成,或者如果信號處理句柄未引發(fā)異常并且套接字被阻塞或已超時則會在超時后引發(fā) TimeoutError。 對于非阻塞型套接字,如果連接被信號中斷則本方法將引發(fā) InterruptedError 異常(或信號處理句柄所引發(fā)的異常)。

引發(fā)一個 審計事件 socket.connect,附帶參數(shù) self、address。

在 3.5 版更改: 本方法現(xiàn)在將等待,直到連接完成,而不是在以下情況拋出 InterruptedError 異常。該情況為,連接被信號中斷,信號處理程序未拋出異常,且套接字阻塞中或已超時(具體解釋請參閱 PEP 475 )。

socket.connect_ex(address)?

類似于 connect(address),但是對于 C 級別的 connect() 調(diào)用返回的錯誤,本函數(shù)將返回錯誤指示器,而不是拋出異常(對于其他問題,如“找不到主機(jī)”,仍然可以拋出異常)。如果操作成功,則錯誤指示器為 0,否則為 errno 變量的值。這對支持如異步連接很有用。

引發(fā)一個 審計事件 socket.connect,附帶參數(shù) selfaddress。

socket.detach()?

將套接字對象置于關(guān)閉狀態(tài),而底層的文件描述符實際并不關(guān)閉。返回該文件描述符,使其可以重新用于其他目的。

3.2 新版功能.

socket.dup()?

創(chuàng)建套接字的副本。

新創(chuàng)建的套接字是 不可繼承的

在 3.4 版更改: 該套接字現(xiàn)在是不可繼承的。

socket.fileno()?

返回套接字的文件描述符(一個小整數(shù)),失敗返回 -1。配合 select.select() 使用很有用。

在 Windows 下,此方法返回的小整數(shù)在允許使用文件描述符的地方無法使用(如 os.fdopen() )。Unix 無此限制。

socket.get_inheritable()?

獲取套接字文件描述符或套接字句柄的 可繼承標(biāo)志 :如果子進(jìn)程可以繼承套接字則為 True,否則為 False。

3.4 新版功能.

socket.getpeername()?

返回套接字連接到的遠(yuǎn)程地址。舉例而言,這可以用于查找遠(yuǎn)程 IPv4/v6 套接字的端口號。(返回的地址格式取決于地址簇 —— 參見上文。)部分系統(tǒng)不支持此函數(shù)。

socket.getsockname()?

返回套接字本身的地址。舉例而言,這可以用于查找 IPv4/v6 套接字的端口號。(返回的地址格式取決于地址簇 —— 參見上文。)

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

返回指定套接字選項的值(參閱 Unix 手冊頁 getsockopt(2) )。所需的符號常量( SO_* 等)已定義在本模塊中。如果未指定 buflen,則認(rèn)為該選項值為整數(shù),由本函數(shù)返回該整數(shù)值。如果指定 buflen,則它定義了用于存放選項值的緩沖區(qū)的最大長度,且該緩沖區(qū)將作為字節(jié)對象返回。對緩沖區(qū)的解碼工作由調(diào)用者自行完成(針對編碼為字節(jié)串的 C 結(jié)構(gòu),其解碼方法請參閱可選的內(nèi)置模塊 struct )。

socket.getblocking()?

如果套接字處于阻塞模式,返回 True,非阻塞模式返回 False。

這相當(dāng)于檢測 socket.gettimeout() == 0。

3.7 新版功能.

socket.gettimeout()?

返回套接字操作相關(guān)的超時秒數(shù)(浮點數(shù)),未設(shè)置超時則返回 None。它反映最后一次調(diào)用 setblocking()settimeout() 后的設(shè)置。

socket.ioctl(control, option)?
平臺

Windows

ioctl() 方法是 WSAIoctl 系統(tǒng)接口的有限接口。請參考 Win32 文檔 以獲取更多信息。

在其他平臺上,可以使用通用的 fcntl.fcntl()fcntl.ioctl() 函數(shù),它們接受套接字對象作為第一個參數(shù)。

當(dāng)前僅支持以下控制碼: SIO_RCVALL、SIO_KEEPALIVE_VALSSIO_LOOPBACK_FAST_PATH。

在 3.6 版更改: 添加了 SIO_LOOPBACK_FAST_PATH。

socket.listen([backlog])?

啟動一個服務(wù)器用于接受連接。如果指定 backlog,則它最低為 0(小于 0 會被置為 0),它指定系統(tǒng)允許暫未 accept 的連接數(shù),超過后將拒絕新連接。未指定則自動設(shè)為合理的默認(rèn)值。

在 3.5 版更改: backlog 參數(shù)現(xiàn)在是可選的。

socket.makefile(mode='r', buffering=None, *, encoding=None, errors=None, newline=None)?

返回與套接字關(guān)聯(lián)的 文件對象。返回的對象的具體類型取決于 makefile() 的參數(shù)。這些參數(shù)的解釋方式與內(nèi)置的 open() 函數(shù)相同,其中 mode 的值僅支持 'r' (默認(rèn)),'w''b'。

套接字必須處于阻塞模式,它可以有超時,但是如果發(fā)生超時,文件對象的內(nèi)部緩沖區(qū)可能會以不一致的狀態(tài)結(jié)尾。

關(guān)閉 makefile() 返回的文件對象不會關(guān)閉原始套接字,除非所有其他文件對象都已關(guān)閉且在套接字對象上調(diào)用了 socket.close()。

備注

在 Windows 上,由 makefile() 創(chuàng)建的文件類對象無法作為帶文件描述符的文件對象使用,如無法作為 subprocess.Popen() 的流參數(shù)。

socket.recv(bufsize[, flags])?

從套接字接收數(shù)據(jù)。返回值是一個字節(jié)對象,表示接收到的數(shù)據(jù)。bufsize 指定一次接收的最大數(shù)據(jù)量??蛇x參數(shù) flags 的含義請參閱 Unix 手冊頁 recv(2),它默認(rèn)為零。

備注

為了最佳匹配硬件和網(wǎng)絡(luò)的實際情況,bufsize 的值應(yīng)為 2 的相對較小的冪,如 4096。

在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號處理程序沒有觸發(fā)異常,此方法現(xiàn)在會重試系統(tǒng)調(diào)用,而不是觸發(fā) InterruptedError 異常 (原因詳見 PEP 475)。

socket.recvfrom(bufsize[, flags])?

從套接字接收數(shù)據(jù)。返回值是一對 (bytes, address),其中 bytes 是字節(jié)對象,表示接收到的數(shù)據(jù),address 是發(fā)送端套接字的地址??蛇x參數(shù) flags 的含義請參閱 Unix 手冊頁 recv(2),它默認(rèn)為零。( address 的格式取決于地址簇 —— 參見上文)

在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號處理程序沒有觸發(fā)異常,此方法現(xiàn)在會重試系統(tǒng)調(diào)用,而不是觸發(fā) InterruptedError 異常 (原因詳見 PEP 475)。

在 3.7 版更改: 對于多播 IPv6 地址,address 的第一項不會再包含 %scope_id 部分。 要獲得完整的 IPv6 地址請使用 getnameinfo()。

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

從套接字接收普通數(shù)據(jù)(至多 bufsize 字節(jié))和輔助數(shù)據(jù)。ancbufsize 參數(shù)設(shè)置用于接收輔助數(shù)據(jù)的內(nèi)部緩沖區(qū)的大?。ㄒ宰止?jié)為單位),默認(rèn)為 0,表示不接收輔助數(shù)據(jù)??梢允褂?CMSG_SPACE()CMSG_LEN() 計算輔助數(shù)據(jù)緩沖區(qū)的合適大小,無法放入緩沖區(qū)的項目可能會被截斷或丟棄。flags 參數(shù)默認(rèn)為 0,其含義與 recv() 中的相同。

返回值是一個四元組: (data, ancdata, msg_flags, address)。data 項是一個 bytes 對象,用于保存接收到的非輔助數(shù)據(jù)。ancdata 項是零個或多個元組 (cmsg_level, cmsg_type, cmsg_data) 組成的列表,表示接收到的輔助數(shù)據(jù)(控制消息):cmsg_levelcmsg_type 是分別表示協(xié)議級別和協(xié)議類型的整數(shù),而 cmsg_data 是保存相關(guān)數(shù)據(jù)的 bytes 對象。msg_flags 項由各種標(biāo)志按位或組成,表示接收消息的情況,詳細(xì)信息請參閱系統(tǒng)文檔。如果接收端套接字?jǐn)嚅_連接,則 address 是發(fā)送端套接字的地址(如果有),否則該值無指定。

某些系統(tǒng)上可以利用 AF_UNIX 套接字通過 sendmsg()recvmsg() 在進(jìn)程之間傳遞文件描述符。使用此功能時(通常僅限于 SOCK_STREAM 套接字),recvmsg() 將在其輔助數(shù)據(jù)中返回以下格式的項 (socket.SOL_SOCKET, socket.SCM_RIGHTS, fds),其中 fds 是一個 bytes 對象,是新文件描述符表示為原生 C int 類型的二進(jìn)制數(shù)組。如果 recvmsg() 在系統(tǒng)調(diào)用返回后拋出異常,它將首先關(guān)閉此機(jī)制接收到的所有文件描述符。

對于僅接收到一部分的輔助數(shù)據(jù)項,一些系統(tǒng)沒有指示其截斷長度。如果某個項目可能超出了緩沖區(qū)的末尾,recvmsg() 將發(fā)出 RuntimeWarning,并返回其在緩沖區(qū)內(nèi)的部分,前提是該對象被截斷于關(guān)聯(lián)數(shù)據(jù)開始后。

在支持 SCM_RIGHTS 機(jī)制的系統(tǒng)上,下方的函數(shù)將最多接收 maxfds 個文件描述符,返回消息數(shù)據(jù)和包含描述符的列表(同時忽略意外情況,如接收到無關(guān)的控制消息)。另請參閱 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)

可用性: 大多數(shù) Unix 平臺,其他平臺也可能可用。

3.3 新版功能.

在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號處理程序沒有觸發(fā)異常,此方法現(xiàn)在會重試系統(tǒng)調(diào)用,而不是觸發(fā) InterruptedError 異常 (原因詳見 PEP 475)。

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

從套接字接收普通數(shù)據(jù)和輔助數(shù)據(jù),其行為與 recvmsg() 相同,但將非輔助數(shù)據(jù)分散到一系列緩沖區(qū)中,而不是返回新的字節(jié)對象。buffers 參數(shù)必須是可迭代對象,它迭代出可供寫入的緩沖區(qū)(如 bytearray 對象),這些緩沖區(qū)將被連續(xù)的非輔助數(shù)據(jù)塊填充,直到數(shù)據(jù)全部寫完或緩沖區(qū)用完為止。在允許使用的緩沖區(qū)數(shù)量上,操作系統(tǒng)可能會有限制( sysconf()SC_IOV_MAX 值)。ancbufsizeflags 參數(shù)的含義與 recvmsg() 中的相同。

返回值為四元組: (nbytes, ancdata, msg_flags, address),其中 nbytes 是寫入緩沖區(qū)的非輔助數(shù)據(jù)的字節(jié)總數(shù),而 ancdata、msg_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---')]

可用性: 大多數(shù) Unix 平臺,其他平臺也可能可用。

3.3 新版功能.

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

從套接字接收數(shù)據(jù),將其寫入 buffer 而不是創(chuàng)建新的字節(jié)串。返回值是一對 (nbytes, address),其中 nbytes 是收到的字節(jié)數(shù),address 是發(fā)送端套接字的地址。可選參數(shù) flags 的含義請參閱 Unix 手冊頁 recv(2),它默認(rèn)為零。( address 的格式取決于地址簇 —— 參見上文)

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

從套接字接收至多 nbytes 個字節(jié),將其寫入緩沖區(qū)而不是創(chuàng)建新的字節(jié)串。如果 nbytes 未指定(或指定為 0),則接收至所給緩沖區(qū)的最大可用大小。返回接收到的字節(jié)數(shù)??蛇x參數(shù) flags 的含義請參閱 Unix 手冊頁 recv(2),它默認(rèn)為零。

socket.send(bytes[, flags])?

發(fā)送數(shù)據(jù)給套接字。本套接字必須已連接到遠(yuǎn)程套接字。可選參數(shù) flags 的含義與上述 recv() 中的相同。本方法返回已發(fā)送的字節(jié)數(shù)。應(yīng)用程序要負(fù)責(zé)檢查所有數(shù)據(jù)是否已發(fā)送,如果僅傳輸了部分?jǐn)?shù)據(jù),程序需要自行嘗試傳輸其余數(shù)據(jù)。有關(guān)該主題的更多信息,請參考 套接字編程指南。

在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號處理程序沒有觸發(fā)異常,此方法現(xiàn)在會重試系統(tǒng)調(diào)用,而不是觸發(fā) InterruptedError 異常 (原因詳見 PEP 475)。

socket.sendall(bytes[, flags])?

發(fā)送數(shù)據(jù)給套接字。本套接字必須已連接到遠(yuǎn)程套接字。可選參數(shù) flags 的含義與上述 recv() 中的相同。與 send() 不同,本方法持續(xù)從 bytes 發(fā)送數(shù)據(jù),直到所有數(shù)據(jù)都已發(fā)送或發(fā)生錯誤為止。成功后會返回 None。出錯后會拋出一個異常,此時并沒有辦法確定成功發(fā)送了多少數(shù)據(jù)。

在 3.5 版更改: 每次成功發(fā)送數(shù)據(jù)后,套接字超時不再重置?,F(xiàn)在,套接字超時是發(fā)送所有數(shù)據(jù)的最大總持續(xù)時間。

在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號處理程序沒有觸發(fā)異常,此方法現(xiàn)在會重試系統(tǒng)調(diào)用,而不是觸發(fā) InterruptedError 異常 (原因詳見 PEP 475)。

socket.sendto(bytes, address)?
socket.sendto(bytes, flags, address)

發(fā)送數(shù)據(jù)給套接字。本套接字不應(yīng)連接到遠(yuǎn)程套接字,而應(yīng)由 address 指定目標(biāo)套接字??蛇x參數(shù) flags 的含義與上述 recv() 中的相同。本方法返回已發(fā)送的字節(jié)數(shù)。( address 的格式取決于地址簇 —— 參見上文。)

引發(fā)一個 審計事件 socket.sendto,附帶參數(shù) self、address。

在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號處理程序沒有觸發(fā)異常,此方法現(xiàn)在會重試系統(tǒng)調(diào)用,而不是觸發(fā) InterruptedError 異常 (原因詳見 PEP 475)。

socket.sendmsg(buffers[, ancdata[, flags[, address]]])?

將普通數(shù)據(jù)和輔助數(shù)據(jù)發(fā)送給套接字,將從一系列緩沖區(qū)中收集非輔助數(shù)據(jù),并將其拼接為一條消息。buffers 參數(shù)指定的非輔助數(shù)據(jù)應(yīng)為可迭代的 字節(jié)類對象 (如 bytes 對象),在允許使用的緩沖區(qū)數(shù)量上,操作系統(tǒng)可能會有限制( sysconf()SC_IOV_MAX 值)。ancdata 參數(shù)指定的輔助數(shù)據(jù)(控制消息)應(yīng)為可迭代對象,迭代出零個或多個 (cmsg_level, cmsg_type, cmsg_data) 元組,其中 cmsg_levelcmsg_type 是分別指定協(xié)議級別和協(xié)議類型的整數(shù),而 cmsg_data 是保存相關(guān)數(shù)據(jù)的字節(jié)類對象。請注意,某些系統(tǒng)(特別是沒有 CMSG_SPACE() 的系統(tǒng))可能每次調(diào)用僅支持發(fā)送一條控制消息。flags 參數(shù)默認(rèn)為 0,與 send() 中的含義相同。如果 address 指定為除 None 以外的值,它將作為消息的目標(biāo)地址。返回值是已發(fā)送的非輔助數(shù)據(jù)的字節(jié)數(shù)。

在支持 SCM_RIGHTS 機(jī)制的系統(tǒng)上,下方的函數(shù)通過一個 AF_UNIX 套接字來發(fā)送文件描述符列表 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))])

可用性: 大多數(shù) Unix 平臺,其他平臺也可能可用。

引發(fā)一個 審計事件 socket.sendmsg,附帶參數(shù) self、address

3.3 新版功能.

在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號處理程序沒有觸發(fā)異常,此方法現(xiàn)在會重試系統(tǒng)調(diào)用,而不是觸發(fā) InterruptedError 異常 (原因詳見 PEP 475)。

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

AF_ALG 套接字定制的 sendmsg() 版本。可為 AF_ALG 套接字設(shè)置模式、IV、AEAD 關(guān)聯(lián)數(shù)據(jù)的長度和標(biāo)志位。

可用性: Linux >= 2.6.38。

3.6 新版功能.

socket.sendfile(file, offset=0, count=None)?

使用高性能的 os.sendfile 發(fā)送文件,直到達(dá)到文件的 EOF 為止,返回已發(fā)送的字節(jié)總數(shù)。file 必須是一個以二進(jìn)制模式打開的常規(guī)文件對象。如果 os.sendfile 不可用(如 Windows)或 file 不是常規(guī)文件,將使用 send() 代替。offset 指示從哪里開始讀取文件。如果指定了 count,它確定了要發(fā)送的字節(jié)總數(shù),而不會持續(xù)發(fā)送直到達(dá)到文件的 EOF。返回時或發(fā)生錯誤時,文件位置將更新,在這種情況下,file.tell() 可用于確定已發(fā)送的字節(jié)數(shù)。套接字必須為 SOCK_STREAM 類型。不支持非阻塞的套接字。

3.5 新版功能.

socket.set_inheritable(inheritable)?

設(shè)置套接字文件描述符或套接字句柄的 可繼承標(biāo)志。

3.4 新版功能.

socket.setblocking(flag)?

設(shè)置套接字為阻塞或非阻塞模式:如果 flag 為 false,則將套接字設(shè)置為非阻塞,否則設(shè)置為阻塞。

本方法是某些 settimeout() 調(diào)用的簡寫:

  • sock.setblocking(True) 相當(dāng)于 sock.settimeout(None)

  • sock.setblocking(False) 相當(dāng)于 sock.settimeout(0.0)

在 3.7 版更改: 本方法不再對 socket.type 屬性設(shè)置 SOCK_NONBLOCK 標(biāo)志。

socket.settimeout(value)?

為阻塞套接字的操作設(shè)置超時。value 參數(shù)可以是非負(fù)浮點數(shù),表示秒,也可以是 None。如果賦為一個非零值,那么如果在操作完成前超過了超時時間 value,后續(xù)的套接字操作將拋出 timeout 異常。如果賦為 0,則套接字將處于非阻塞模式。如果指定為 None,則套接字將處于阻塞模式。

更多信息請查閱 關(guān)于套接字超時的說明。

在 3.7 版更改: 本方法不再修改 socket.type 屬性的 SOCK_NONBLOCK 標(biāo)志。

socket.setsockopt(level, optname, value: int)?
socket.setsockopt(level, optname, value: buffer)
socket.setsockopt(level, optname, None, optlen: int)

設(shè)置給定套接字選項的值(參閱 Unix 手冊頁 setsockopt(2) )。所需的符號常量( SO_* 等)已定義在本 socket 模塊中。該值可以是整數(shù)、None 或表示緩沖區(qū)的 字節(jié)類對象。在后一種情況下,由調(diào)用者確保字節(jié)串中包含正確的數(shù)據(jù)位(關(guān)于將 C 結(jié)構(gòu)體編碼為字節(jié)串的方法,請參閱可選的內(nèi)置模塊 struct )。當(dāng) value 設(shè)置為 None 時,必須設(shè)置 optlen 參數(shù)。這相當(dāng)于調(diào)用 setsockopt() C 函數(shù)時使用了 optval=NULLoptlen=optlen 參數(shù)。

在 3.5 版更改: 現(xiàn)在接受可寫的 字節(jié)類對象。

在 3.6 版更改: 添加了 setsockopt(level, optname, None, optlen: int) 調(diào)用形式。

socket.shutdown(how)?

關(guān)閉一半或全部的連接。如果 howSHUT_RD,則后續(xù)不再允許接收。如果 howSHUT_WR,則后續(xù)不再允許發(fā)送。如果 howSHUT_RDWR,則后續(xù)的發(fā)送和接收都不允許。

socket.share(process_id)?

復(fù)制套接字,并準(zhǔn)備將其與目標(biāo)進(jìn)程共享。目標(biāo)進(jìn)程必須以 process_id 形式提供。然后可以利用某種形式的進(jìn)程間通信,將返回的字節(jié)對象傳遞給目標(biāo)進(jìn)程,還可以使用 fromshare() 在新進(jìn)程中重新創(chuàng)建套接字。一旦本方法調(diào)用完畢,就可以安全地將套接字關(guān)閉,因為操作系統(tǒng)已經(jīng)為目標(biāo)進(jìn)程復(fù)制了該套接字。

可用性: Windows。

3.3 新版功能.

注意此處沒有 read()write() 方法,請使用不帶 flags 參數(shù)的 recv()send() 來替代。

套接字對象還具有以下(只讀)屬性,這些屬性與傳入 socket 構(gòu)造函數(shù)的值相對應(yīng)。

socket.family?

套接字的協(xié)議簇。

socket.type?

套接字的類型。

socket.proto?

套接字的協(xié)議。

關(guān)于套接字超時的說明?

一個套接字對象可以處于以下三種模式之一:阻塞、非阻塞或超時。套接字默認(rèn)以阻塞模式創(chuàng)建,但是可以調(diào)用 setdefaulttimeout() 來更改。

  • blocking mode (阻塞模式)中,操作將阻塞,直到操作完成或系統(tǒng)返回錯誤(如連接超時)。

  • non-blocking mode (非阻塞模式)中,如果操作無法立即完成,則操作將失敗(不幸的是,不同系統(tǒng)返回的錯誤不同):位于 select 中的函數(shù)可用于了解套接字何時以及是否可以讀取或?qū)懭搿?/p>

  • timeout mode (超時模式)下,如果無法在指定的超時內(nèi)完成操作(拋出 timeout 異常),或如果系統(tǒng)返回錯誤,則操作將失敗。

備注

在操作系統(tǒng)層面上,超時模式 下的套接字在內(nèi)部都設(shè)置為非阻塞模式。同時,阻塞和超時模式在文件描述符和套接字對象之間共享,這些描述符和對象均應(yīng)指向同一個網(wǎng)絡(luò)端點。如果,比如你決定使用套接字的 fileno(),這一實現(xiàn)細(xì)節(jié)可能導(dǎo)致明顯的結(jié)果。

超時與 connect 方法?

connect() 操作也受超時設(shè)置的約束,通常建議在調(diào)用 connect() 之前調(diào)用 settimeout(),或?qū)⒊瑫r參數(shù)直接傳遞給 create_connection()。但是,無論 Python 套接字超時設(shè)置如何,系統(tǒng)網(wǎng)絡(luò)棧都有可能返回自帶的連接超時錯誤。

超時與 accept 方法?

如果 getdefaulttimeout() 的值不是 None,則 accept() 方法返回的套接字將繼承該超時值。若是 None,返回的套接字行為取決于偵聽套接字的設(shè)置:

  • 如果偵聽套接字處于 阻塞模式超時模式,則 accept() 返回的套接字處于 阻塞模式

  • 如果偵聽套接字處于 非阻塞模式,那么 accept() 返回的套接字是阻塞還是非阻塞取決于操作系統(tǒng)。如果要確??缙脚_時的正確行為,建議手動覆蓋此設(shè)置。

示例?

以下是 4 個使用 TCP/IP 協(xié)議的最小示例程序:一臺服務(wù)器,它將收到的所有數(shù)據(jù)原樣返回(僅服務(wù)于一個客戶端),還有一個使用該服務(wù)器的客戶端。注意,服務(wù)器必須按序執(zhí)行 socket(), bind(), listen(), accept() (可能需要重復(fù)執(zhí)行 accept() 以服務(wù)多個客戶端),而客戶端僅需要按序執(zhí)行 socket(), connect()。還須注意,服務(wù)器不在偵聽套接字上發(fā)送 sendall()/recv(),而是在 accept() 返回的新套接字上發(fā)送。

前兩個示例僅支持 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。 服務(wù)端將監(jiān)聽第一個可用的地址族(它本應(yīng)同時監(jiān)聽兩個)。 在大多數(shù)支持 IPv6 的系統(tǒng)上,IPv6 將有優(yōu)先權(quán)并且服務(wù)端可能不會接受 IPv4 流量。 客戶端將嘗試連接到作為名稱解析結(jié)果被返回的所有地址,并將流量發(fā)送給連接成功的第一個地址。

# 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 上使用原始套接字編寫一個非常簡單的網(wǎng)絡(luò)嗅探器。 這個例子需要管理員權(quán)限來修改接口:

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 接口與采用原始套接字協(xié)議的 CAN 網(wǎng)絡(luò)進(jìn)行通信。 要改為通過廣播管理器協(xié)議來使用 CAN,則要用以下方式打開一個 socket:

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

在綁定 (CAN_RAW) 或連接 (CAN_BCM) socket 之后,你將可以在 socket 對象上正常使用 socket.send() 以及 socket.recv() 操作(及同類操作)。

最后一個例子可能需要特別的權(quán)限:

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

多次運行一個示例,且每次執(zhí)行之間等待時間過短,可能導(dǎo)致這個錯誤:

OSError: [Errno 98] Address already in use

這是因為前一次運行使套接字處于 TIME_WAIT 狀態(tài),無法立即重用。

要防止這種情況,需要設(shè)置一個 socket 標(biāo)志 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 標(biāo)志告訴內(nèi)核將處于 TIME_WAIT 狀態(tài)的本地套接字重新使用,而不必等到固有的超時到期。

參見

關(guān)于套接字編程(C 語言)的介紹,請參閱以下文章:

  • An Introductory 4.3BSD Interprocess Communication Tutorial,作者 Stuart Sechrest

  • An Advanced 4.3BSD Interprocess Communication Tutorial,作者 Samuel J. Leffler et al,

兩篇文章都在 UNIX 開發(fā)者手冊,補(bǔ)充文檔 1(第 PS1:7 和 PS1:8 節(jié))中。那些特定于平臺的參考資料,它們包含與套接字有關(guān)的各種系統(tǒng)調(diào)用,也是套接字語義細(xì)節(jié)的寶貴信息來源。對于 Unix,請參考手冊頁。對于 Windows,請參閱 WinSock(或 Winsock 2)規(guī)范。如果需要支持 IPv6 的 API,讀者可能希望參考 RFC 3493,標(biāo)題為 Basic Socket Interface Extensions for IPv6。