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)建選項,此模塊提供了各種 socket 協(xié)議簇。

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

  • 一個綁定在文件系統(tǒng)節(jié)點上的 AF_UNIX 套接字的地址表示為一個字符串,使用文件系統(tǒng)字符編碼和 'surrogateescape' 錯誤回調(diào)方法(see PEP 383)。一個地址在 Linux 的抽象命名空間被返回為帶有初始的 null 字節(jié)的 bytes-like object ;注意在這個命名空間種的套接字可能與普通文件系統(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)域名表示法之內(nèi)主機名或者一個 IPv4 地址的字符串,例如 'daring.cwi.nl''100.50.200.5',port 是一個整數(shù)。

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

  • 對于 AF_INET6 地址族,使用一個四元組 (host, port, flowinfo, scopeid)flowinfoscopeid 代表了 C 庫里 struct sockaddr_in6 中的 sin6_flowinfosin6_scope_id 成員。 對于 socket 模塊中的方法, flowinfoscopeid 可以被省略,只為了向后兼容。注意,scopeid 的省略可能會導(dǎo)致 IPv6 地址的操作范圍問題。

    在 3.7 版更改: 對于多播地址(其 scopeid 是有意義的),地址 可能不包含 %scope``(或 ``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)或擴展標(biāo)識符)。

  • 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 為字符串格式的藍牙地址,psm 是一個整數(shù)。

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

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

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

    • BTPROTO_SCO 接受 bdaddr,其中 bdaddrbytes 對象,其中含有字符串格式的藍牙地址(如 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、hash、skcipherrng

    • 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 用于支持虛擬機與宿主機之間的通訊。該套接字用 (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 (默認) - 數(shù)據(jù)包尋址到本地宿主機。

      • PACKET_BROADCAST - 物理層廣播報文。

      • PACKET_MULTIHOST - 數(shù)據(jù)包發(fā)送到物理層多播地址。

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

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

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

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

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

所有的錯誤都拋出異常。對于無效參數(shù)類型和內(nèi)存溢出異常情況可能拋出普通異常;從 Python 3.3 開始,與套接字或地址語義有關(guān)的錯誤拋出 OSError 或它的子類之一(常用 socket.error)。

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

模塊內(nèi)容?

socket 模塊導(dǎo)出以下元素。

異常?

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?

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

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

常量?

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è)置一些原子性的 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 頭文件中有定義的符號會在本模塊中定義,部分符號提供了默認值。

在 3.6 版更改: 添加了 SO_DOMAINSO_PROTOCOL、SO_PEERSECSO_PASSSEC、TCP_USER_TIMEOUT、TCP_CONGESTION。

在 3.6.5 版更改: 在 Windows 上,如果 Windows 運行時支持,則 TCP_FASTOPENTCP_KEEPCNT 可用。

在 3.7 版更改: 添加了 TCP_NOTSENT_LOWAT

在 Windows 上,如果 Windows 運行時支持,則 TCP_KEEPIDLE、TCP_KEEPINTVL 可用。

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

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

可用性: Linux >= 2.6.25。

3.3 新版功能.

socket.CAN_BCM?
CAN_BCM_*

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

可用性: Linux >= 2.6.25。

3.4 新版功能.

socket.CAN_RAW_FD_FRAMES?

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

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

可用性: Linux >= 3.6。

3.5 新版功能.

socket.CAN_ISOTP?

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

可用性: Linux >= 2.6.25。

3.7 新版功能.

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 宿主機/虛擬機通訊的常量。

可用性: Linux >= 4.8。

3.7 新版功能.

可用性: BSD、OSX。

3.4 新版功能.

socket.has_ipv6?

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

socket.BDADDR_ANY?
socket.BDADDR_LOCAL?

這些是字符串常量,包含藍牙地址,這些地址具有特殊含義。例如,當(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 上不可用。

函數(shù)?

創(chuàng)建套接字?

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

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

使用給定的地址簇、套接字類型和協(xié)議號創(chuàng)建一個新的套接字。地址簇應(yīng)為 AF_INET (默認)、AF_INET6、AF_UNIX、AF_CANAF_PACKETAF_RDS 其中之一。套接字類型應(yīng)為 SOCK_STREAM (默認)、SOCK_DGRAM、SOCK_RAW 或其他 SOCK_ 常量之一。協(xié)議號通常為零,可以省略,或者在地址簇為 AF_CAN 的情況下,協(xié)議號應(yīng)為 CAN_RAW、CAN_BCMCAN_ISOTP 之一。

如果指定了 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)建的套接字是 不可繼承的。

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

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

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

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

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

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

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

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

連接到一個 TCP 服務(wù),該服務(wù)正在偵聽 Internet address (用二元組 (host, port) 表示)。連接后返回套接字對象。這是比 socket.connect() 更高級的函數(shù):如果 host 是非數(shù)字主機名,它將嘗試從 AF_INETAF_INET6 解析它,然后依次嘗試連接到所有可能的地址,直到連接成功。這使得編寫兼容 IPv4 和 IPv6 的客戶端變得容易。

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

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

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

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 守護程序啟動的服務(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。

可以指定 family、typeproto 參數(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ù)。如果 flags 參數(shù)有一部分是 AI_CANONNAME,那么 canonname 將是表示 host 的規(guī)范名稱的字符串。否則 canonname 將為空。sockaddr 是一個表示套接字地址的元組,具體格式取決于返回的 family (對于 AF_INET,是一個 (address, port) 二元組,對于 AF_INET6,是一個 (address, port, flow info, scope id) 四元組),可以用于傳遞給 socket.connect() 方法。

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

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

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

socket.getfqdn([name])?

返回 name 的全限定域名 (Fully Qualified Domain Name -- FQDN)。如果 name 省略或為空,則將其解釋為本地主機。為了查找全限定名稱,首先將檢查由 gethostbyaddr() 返回的主機名,然后是主機的別名(如果存在)。選中第一個包含句點的名字。如果無法獲取全限定域名,則返回由 gethostname() 返回的主機名。

socket.gethostbyname(hostname)?

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

socket.gethostbyname_ex(hostname)?

將主機名轉(zhuǎn)換為 IPv4 地址格式的擴展接口。返回三元組 (hostname, aliaslist, ipaddrlist),其中 hostname 是響應(yīng)給定 ip_address 的主要主機名,aliaslist 是相同地址的其他可用主機名的列表(可能為空),而 ipaddrlist 是 IPv4 地址列表,包含相同主機名、相同接口的不同地址(通常是一個地址,但不總是如此)。gethostbyname_ex() 不支持 IPv6 名稱解析,應(yīng)使用 getaddrinfo() 來支持 IPv4/v6 雙協(xié)議棧。

socket.gethostname()?

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

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

socket.gethostbyaddr(ip_address)?

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

socket.getnameinfo(sockaddr, flags)?

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

對于 IPv6 地址,如果 sockaddr 包含有意義的 scopeid,則將 %scope 附加到 host 部分。這種情況通常發(fā)生在多播地址上。

socket.getprotobyname(protocolname)?

將 Internet 協(xié)議名稱(如 'icmp' )轉(zhuǎn)換為常量,該常量適用于 socket() 函數(shù)的第三個(可選)參數(shù)。通常只有在 "raw" 模式 (SOCK_RAW) 中打開的套接字才需要使用該常量。對于正常的套接字模式,協(xié)議省略或為零時,會自動選擇正確的協(xié)議。

socket.getservbyname(servicename[, protocolname])?

將 Internet 服務(wù)名稱和協(xié)議名稱轉(zhuǎn)換為該服務(wù)的端口號。協(xié)議名稱是可選的,如果提供的話應(yīng)為 'tcp''udp',否則將匹配出所有協(xié)議。

socket.getservbyport(port[, protocolname])?

將 Internet 端口號和協(xié)議名稱轉(zhuǎn)換為該服務(wù)的服務(wù)名稱。協(xié)議名稱是可選的,如果提供的話應(yīng)為 'tcp''udp',否則將匹配出所有協(xié)議。

socket.ntohl(x)?

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

socket.ntohs(x)?

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

3.7 版后已移除: 如果 x 不符合 16 位無符號整數(shù),但符合 C 語言的正整數(shù),則它會被靜默截斷為 16 位無符號整數(shù)。此靜默截斷功能已棄用,未來版本的 Python 將對此拋出異常。

socket.htonl(x)?

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

socket.htons(x)?

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

3.7 版后已移除: 如果 x 不符合 16 位無符號整數(shù),但符合 C 語言的正整數(shù),則它會被靜默截斷為 16 位無符號整數(shù)。此靜默截斷功能已棄用,未來版本的 Python 將對此拋出異常。

socket.inet_aton(ip_string)?

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

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

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

socket.inet_pton(address_family, ip_string)?

將特定地址簇的 IP 地址(字符串)轉(zhuǎ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()?

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

socket.setdefaulttimeout(timeout)?

設(shè)置用于新套接字對象的默認超時(以秒為單位的浮點數(shù))。首次導(dǎo)入 socket 模塊時,默認值為 None。可能的取值及其各自的含義請參閱 settimeout()。

socket.sethostname(name)?

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

可用性: Unix。

3.3 新版功能.

socket.if_nameindex()?

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

可用性: Unix。

3.3 新版功能.

socket.if_nametoindex(if_name)?

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

可用性: Unix。

3.3 新版功能.

socket.if_indextoname(if_index)?

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

可用性: Unix。

3.3 新版功能.

套接字對象?

套接字對象具有以下方法。除了 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 的格式取決于地址簇 —— 參見上文)

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 處的遠程套接字。( address 的格式取決于地址簇 —— 參見上文)

如果連接被信號中斷,則本方法將等待,直到連接完成。如果信號處理程序未拋出異常,且套接字阻塞中或已超時,則在超時后拋出 socket.timeout。對于非阻塞套接字,如果連接被信號中斷,則本方法將拋出 InterruptedError 異常(或信號處理程序拋出的異常)。

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

socket.connect_ex(address)?

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

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)志 :如果子進程可以繼承套接字則為 True,否則為 False。

3.4 新版功能.

socket.getpeername()?

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

socket.getsockname()?

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

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

返回指定套接字選項的值(參閱 Unix 手冊頁 getsockopt(2) )。所需的符號常量( SO_* 等)已定義在本模塊中。如果未指定 buflen,則認為該選項值為整數(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è)為合理的默認值。

在 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' (默認),'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),它默認為零。

注解

為了最佳匹配硬件和網(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),它默認為零。( address 的格式取決于地址簇 —— 參見上文)

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

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

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

從套接字接收普通數(shù)據(jù)(至多 bufsize 字節(jié))和輔助數(shù)據(jù)。ancbufsize 參數(shù)設(shè)置用于接收輔助數(shù)據(jù)的內(nèi)部緩沖區(qū)的大?。ㄒ宰止?jié)為單位),默認為 0,表示不接收輔助數(shù)據(jù)。可以使用 CMSG_SPACE()CMSG_LEN() 計算輔助數(shù)據(jù)緩沖區(qū)的合適大小,無法放入緩沖區(qū)的項目可能會被截斷或丟棄。flags 參數(shù)默認為 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)志按位或組成,表示接收消息的情況,詳細信息請參閱系統(tǒng)文檔。如果接收端套接字?jǐn)嚅_連接,則 address 是發(fā)送端套接字的地址(如果有),否則該值無指定。

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

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

在支持 SCM_RIGHTS 機制的系統(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ā)送端套接字的地址??蛇x參數(shù) flags 的含義請參閱 Unix 手冊頁 recv(2),它默認為零。( address 的格式取決于地址簇 —— 參見上文)

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

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

socket.send(bytes[, flags])?

發(fā)送數(shù)據(jù)給套接字。本套接字必須已連接到遠程套接字??蛇x參數(shù) flags?的含義與上述 recv() 中的相同。本方法返回已發(fā)送的字節(jié)數(shù)。應(yīng)用程序要負責(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ù)給套接字。本套接字必須已連接到遠程套接字??蛇x參數(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)連接到遠程套接字,而應(yīng)由 address 指定目標(biāo)套接字??蛇x參數(shù) flags 的含義與上述 recv() 中的相同。本方法返回已發(fā)送的字節(jié)數(shù)。( 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ù)默認為 0,與 send() 中的含義相同。如果 address 指定為除 None 以外的值,它將作為消息的目標(biāo)地址。返回值是已發(fā)送的非輔助數(shù)據(jù)的字節(jié)數(shù)。

在支持 SCM_RIGHTS 機制的系統(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 平臺,其他平臺也可能可用。

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ā)送文件,直到達到文件的 EOF 為止,返回已發(fā)送的字節(jié)總數(shù)。file 必須是一個以二進制模式打開的常規(guī)文件對象。如果 os.sendfile 不可用(如 Windows)或 file 不是常規(guī)文件,將使用 send() 代替。offset 指示從哪里開始讀取文件。如果指定了 count,它確定了要發(fā)送的字節(jié)總數(shù),而不會持續(xù)發(fā)送直到達到文件的 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ù)可以是非負浮點數(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)進程共享。目標(biāo)進程必須以 process_id 形式提供。然后可以利用某種形式的進程間通信,將返回的字節(jié)對象傳遞給目標(biāo)進程,還可以使用 fromshare() 在新進程中重新創(chuàng)建套接字。一旦本方法調(diào)用完畢,就可以安全地將套接字關(guān)閉,因為操作系統(tǒng)已經(jīng)為目標(biāo)進程復(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)于套接字超時的說明?

一個套接字對象可以處于以下三種模式之一:阻塞、非阻塞或超時。套接字默認以阻塞模式創(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)細節(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ò)進行通信。 要改為通過廣播管理器協(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')

如果多次運行示例,且兩次運行間隔很短,可能引發(fā)此錯誤:

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