socket --- 底層網(wǎng)絡(luò)接口?
源代碼: Lib/socket.py
這個(gè)模塊提供了訪問BSD*套接字*的接口。在所有現(xiàn)代Unix系統(tǒng)、Windows、macOS和其他一些平臺(tái)上可用。
注解
一些行為可能因平臺(tái)不同而異,因?yàn)檎{(diào)用的是操作系統(tǒng)的套接字API。
這個(gè)Python接口是用Python的面向?qū)ο箫L(fēng)格對(duì)Unix系統(tǒng)調(diào)用和套接字庫接口的直譯:函數(shù) socket() 返回一個(gè) 套接字對(duì)象 ,其方法是對(duì)各種套接字系統(tǒng)調(diào)用的實(shí)現(xiàn)。形參類型一般與C接口相比更高級(jí):例如在Python文件 read() 和 write()?操作中,接收操作的緩沖區(qū)分配是自動(dòng)的,發(fā)送操作的緩沖區(qū)長(zhǎng)度是隱式的。
參見
- 模塊
socketserver 用于簡(jiǎn)化網(wǎng)絡(luò)服務(wù)端編寫的類。
- 模塊
ssl 套接字對(duì)象的TLS/SSL封裝。
套接字協(xié)議族?
根據(jù)系統(tǒng)以及構(gòu)建選項(xiàng),此模塊提供了各種 socket 協(xié)議簇。
特定的 socket 對(duì)象需要的地址格式將根據(jù)此 socket 對(duì)象被創(chuàng)建時(shí)指定的地址族被自動(dòng)選擇。socket 地址表示如下:
一個(gè)綁定在文件系統(tǒng)節(jié)點(diǎn)上的
AF_UNIX套接字的地址表示為一個(gè)字符串,使用文件系統(tǒng)字符編碼和'surrogateescape'錯(cuò)誤回調(diào)方法(see PEP 383)。一個(gè)地址在 Linux 的抽象命名空間被返回為帶有初始的 null 字節(jié)的 bytes-like object ;注意在這個(gè)命名空間種的套接字可能與普通文件系統(tǒng)套接字通信,所以打算運(yùn)行在 Linux 上的程序可能需要解決兩種地址類型。當(dāng)傳遞為參數(shù)時(shí),一個(gè)字符串或字節(jié)類對(duì)象可以用于任一類型的地址。在 3.3 版更改: 以前,
AF_UNIX套接字路徑被假設(shè)使用 UTF-8 編碼。在 3.5 版更改: 現(xiàn)在支持可寫的 字節(jié)類對(duì)象。
一對(duì)
(host, port)被用于AF_INET地址族,host 是一個(gè)代表互聯(lián)網(wǎng)域名表示法之內(nèi)主機(jī)名或者一個(gè) IPv4 地址的字符串,例如'daring.cwi.nl'或'100.50.200.5',port 是一個(gè)整數(shù)。對(duì)于 IPv4 地址,有兩種可接受的特殊形式被用來代替一個(gè)主機(jī)地址:
''代表INADDR_ANY,用來綁定到所有接口;字符串'<broadcast>'代表INADDR_BROADCAST。此行為不兼容 IPv6,因此,如果你的 Python 程序打算支持 IPv6,則可能需要避開這些。
對(duì)于
AF_INET6地址族,使用一個(gè)四元組(host, port, flowinfo, scopeid), flowinfo 和 scopeid 代表了 C 庫里struct sockaddr_in6中的sin6_flowinfo和sin6_scope_id成員。 對(duì)于socket模塊中的方法, flowinfo 和 scopeid 可以被省略,只為了向后兼容。注意,scopeid 的省略可能會(huì)導(dǎo)致 IPv6 地址的操作范圍問題。在 3.7 版更改: 對(duì)于多播地址(其 scopeid 是有意義的),地址 可能不包含
%scope``(或 ``zone id)部分。該信息是多余的,可以放心省略(推薦)。AF_NETLINK套接字由一對(duì)(pid, groups)表示。指定
AF_TIPC地址族可以使用僅 Linux 支持的 TIPC 協(xié)議。TIPC 是一種開放的、非基于 IP 的網(wǎng)絡(luò)協(xié)議,旨在用于集群計(jì)算環(huán)境。其地址用元組表示,其中的字段取決于地址類型。一般元組形式為(addr_type, v1, v2, v3 [, scope]),其中:addr_type 取
TIPC_ADDR_NAMESEQ、TIPC_ADDR_NAME或TIPC_ADDR_ID中的一個(gè)。scope 取
TIPC_ZONE_SCOPE、TIPC_CLUSTER_SCOPE和TIPC_NODE_SCOPE中的一個(gè)。如果 addr_type 為
TIPC_ADDR_NAME,那么 v1 是服務(wù)器類型,v2 是端口標(biāo)識(shí)符,v3 應(yīng)為 0。如果 addr_type 為
TIPC_ADDR_NAMESEQ,那么 v1 是服務(wù)器類型,v2 是端口號(hào)下限,而 v3 是端口號(hào)上限。如果 addr_type 為
TIPC_ADDR_ID,那么 v1 是節(jié)點(diǎn) (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é)議接受一個(gè)元組(interface, rx_addr, tx_addr),其中兩個(gè)額外參數(shù)都是無符號(hào)長(zhǎng)整數(shù),都表示 CAN 標(biāo)識(shí)符(標(biāo)準(zhǔn)或擴(kuò)展標(biāo)識(shí)符)。
PF_SYSTEM協(xié)議簇的SYSPROTO_CONTROL協(xié)議接受一個(gè)字符串或元組(id, unit)。其中字符串是內(nèi)核控件的名稱,該控件使用動(dòng)態(tài)分配的 ID。而如果 ID 和內(nèi)核控件的單元 (unit) 編號(hào)都已知,或使用了已注冊(cè)的 ID,可以采用元組。3.3 新版功能.
AF_BLUETOOTH支持以下協(xié)議和地址格式:BTPROTO_L2CAP接受(bdaddr, psm),其中bdaddr為字符串格式的藍(lán)牙地址,psm是一個(gè)整數(shù)。BTPROTO_RFCOMM接受(bdaddr, channel),其中bdaddr為字符串格式的藍(lán)牙地址,channel是一個(gè)整數(shù)。BTPROTO_HCI接受(device_id,),其中device_id為整數(shù)或字符串,它表示接口對(duì)應(yīng)的藍(lán)牙地址(具體取決于你的系統(tǒng),NetBSD 和 DragonFlyBSD 需要藍(lán)牙地址字符串,其他系統(tǒng)需要整數(shù))。在 3.2 版更改: 添加 NetBSD 和 DragonFlyBSD 支持。
BTPROTO_SCO接受bdaddr,其中bdaddr是bytes對(duì)象,其中含有字符串格式的藍(lán)牙地址(如b'12:23:34:45:56:67'),F(xiàn)reeBSD 不支持此協(xié)議。
AF_ALG是一個(gè)僅 Linux 可用的、基于套接字的接口,用于連接內(nèi)核加密算法。算法套接字可用包括 2 至 4 個(gè)元素的元組來配置(type, name [, feat [, mask]]),其中:type 是表示算法類型的字符串,如
aead、hash、skcipher或rng。name 是表示算法類型和操作模式的字符串,如
sha256、hmac(sha256)、cbc(aes)或drbg_nopr_ctr_aes256。feat 和 mask 是無符號(hào) 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是一個(gè)底層接口,直接連接至網(wǎng)卡。數(shù)據(jù)包使用元組(ifname, proto[, pkttype[, hatype[, addr]]])表示,其中:ifname - 指定設(shè)備名稱的字符串。
proto - 一個(gè)用網(wǎng)絡(luò)字節(jié)序表示的整數(shù),指定以太網(wǎng)協(xié)議版本號(hào)。
pkttype - 指定數(shù)據(jù)包類型的整數(shù)(可選):
PACKET_HOST(默認(rèn)) - 數(shù)據(jù)包尋址到本地宿主機(jī)。PACKET_BROADCAST- 物理層廣播報(bào)文。PACKET_MULTIHOST- 數(shù)據(jù)包發(fā)送到物理層多播地址。PACKET_OTHERHOST- 被(處于混雜模式的)網(wǎng)卡驅(qū)動(dòng)捕獲的、發(fā)送到其他主機(jī)的數(shù)據(jù)包。PACKET_OUTGOING- 來自本地主機(jī)的、回環(huán)到一個(gè)套接字的數(shù)據(jù)包。
hatype - 可選整數(shù),指定 ARP 硬件地址類型。
addr - 可選的類字節(jié)串對(duì)象,用于指定硬件物理地址,其解釋取決于各設(shè)備。
如果你在 IPv4/v6 套接字地址的 host 部分中使用了一個(gè)主機(jī)名,此程序可能會(huì)表現(xiàn)不確定行為,因?yàn)?Python 使用 DNS 解析返回的第一個(gè)地址。套接字地址在實(shí)際的 IPv4/v6 中以不同方式解析,根據(jù) DNS 解析和/或 host 配置。為了確定行為,在 host 部分中使用數(shù)字地址。
所有的錯(cuò)誤都拋出異常。對(duì)于無效參數(shù)類型和內(nèi)存溢出異常情況可能拋出普通異常;從 Python 3.3 開始,與套接字或地址語義有關(guān)的錯(cuò)誤拋出 OSError 或它的子類之一(常用 socket.error)。
可以用 setblocking() 設(shè)置非阻塞模式。一個(gè)基于超時(shí)的 generalization 通過 settimeout() 支持。
模塊內(nèi)容?
socket 模塊導(dǎo)出以下元素。
異常?
-
exception
socket.herror? OSError的子類,本異常通常表示與地址相關(guān)的錯(cuò)誤,比如那些在 POSIX C API 中使用了 h_errno 的函數(shù),包括gethostbyname_ex()和gethostbyaddr()。附帶的值是一對(duì)(h_errno, string),代表庫調(diào)用返回的錯(cuò)誤。h_errno 是一個(gè)數(shù)字,而 string 表示 h_errno 的描述,它們由 C 函數(shù)hstrerror()返回。在 3.3 版更改: 此類是
OSError的子類。
-
exception
socket.gaierror? OSError的子類,本異常來自getaddrinfo()和getnameinfo(),表示與地址相關(guān)的錯(cuò)誤。附帶的值是一對(duì)(error, string),代表庫調(diào)用返回的錯(cuò)誤。string 表示 error 的描述,它由 C 函數(shù)gai_strerror()返回。數(shù)字值 error 與本模塊中定義的EAI_*常量之一匹配。在 3.3 版更改: 此類是
OSError的子類。
-
exception
socket.timeout? OSError的子類,當(dāng)套接字發(fā)生超時(shí),且事先已調(diào)用過settimeout()(或隱式地通過setdefaulttimeout())啟用了超時(shí),則會(huì)拋出此異常。附帶的值是一個(gè)字符串,其值總是 "timed out"。在 3.3 版更改: 此類是
OSError的子類。
常量?
AF_* 和 SOCK_* 常量現(xiàn)在都在
AddressFamily和SocketKind這兩個(gè)IntEnum集合內(nèi)。3.4 新版功能.
-
socket.AF_UNIX? -
socket.AF_INET? -
socket.AF_INET6? 這些常量表示地址(和協(xié)議)簇,用于
socket()的第一個(gè)參數(shù)。如果AF_UNIX常量未定義,即表示不支持該協(xié)議。不同系統(tǒng)可能會(huì)有更多其他常量可用。
-
socket.SOCK_STREAM? -
socket.SOCK_DGRAM? -
socket.SOCK_RAW? -
socket.SOCK_RDM? -
socket.SOCK_SEQPACKET? 這些常量表示套接字類型,用于
socket()的第二個(gè)參數(shù)。不同系統(tǒng)可能會(huì)有更多其他常量可用。(一般只有SOCK_STREAM和SOCK_DGRAM可用)
-
socket.SOCK_CLOEXEC? -
socket.SOCK_NONBLOCK? 這兩個(gè)常量(如果已定義)可以與上述套接字類型結(jié)合使用,并允許你設(shè)置一些原子性的 flags (從而避免可能的競(jìng)爭(zhēng)條件和單獨(dú)調(diào)用的需要)。
參見
Secure File Descriptor Handling (安全地處理文件描述符) 提供了更詳盡的解釋。
可用性: 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é)議部分,同時(shí)也定義在本 socket 模塊中。它們通常用于套接字對(duì)象的
setsockopt()和getsockopt()方法的參數(shù)中。在大多數(shù)情況下,僅那些在 Unix 頭文件中有定義的符號(hào)會(huì)在本模塊中定義,部分符號(hào)提供了默認(rèn)值。在 3.6 版更改: 添加了
SO_DOMAIN、SO_PROTOCOL、SO_PEERSEC、SO_PASSSEC、TCP_USER_TIMEOUT、TCP_CONGESTION。在 3.6.5 版更改: 在 Windows 上,如果 Windows 運(yùn)行時(shí)支持,則
TCP_FASTOPEN、TCP_KEEPCNT可用。在 3.7 版更改: 添加了
TCP_NOTSENT_LOWAT。在 Windows 上,如果 Windows 運(yùn)行時(shí)支持,則
TCP_KEEPIDLE、TCP_KEEPINTVL可用。
-
socket.AF_CAN? -
socket.PF_CAN? -
SOL_CAN_* -
CAN_* 此列表內(nèi)的許多常量,記載在 Linux 文檔中,同時(shí)也定義在本 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 支持,默認(rèn)是禁用的。它使應(yīng)用程序可以發(fā)送 CAN 和 CAN FD 幀。但是,從套接字讀取時(shí),也必須同時(shí)接受 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 文檔中,同時(shí)也定義在本 socket 模塊中。
可用性: Linux >= 2.2。
-
socket.AF_RDS? -
socket.PF_RDS? -
socket.SOL_RDS? -
RDS_* 此列表內(nèi)的許多常量,記載在 Linux 文檔中,同時(shí)也定義在本 socket 模塊中。
可用性: Linux >= 2.6.30。
3.3 新版功能.
-
socket.SIO_RCVALL? -
socket.SIO_KEEPALIVE_VALS? -
socket.SIO_LOOPBACK_FAST_PATH? -
RCVALL_* Windows 的 WSAIoctl() 的常量。這些常量用于套接字對(duì)象的
ioctl()方法的參數(shù)。在 3.6 版更改: 添加了
SIO_LOOPBACK_FAST_PATH。
-
TIPC_* TIPC 相關(guān)常量,與 C socket API 導(dǎo)出的常量一致。更多信息請(qǐng)參閱 TIPC 文檔。
-
socket.AF_VSOCK? -
socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID? -
VMADDR* -
SO_VM* 用于 Linux 宿主機(jī)/虛擬機(jī)通訊的常量。
可用性: Linux >= 4.8。
3.7 新版功能.
-
socket.has_ipv6? 本常量為一個(gè)布爾值,該值指示當(dāng)前平臺(tái)是否支持 IPv6。
-
socket.BDADDR_ANY? -
socket.BDADDR_LOCAL? 這些是字符串常量,包含藍(lán)牙地址,這些地址具有特殊含義。例如,當(dāng)用
BTPROTO_RFCOMM指定綁定套接字時(shí),BDADDR_ANY表示“任何地址”。
-
socket.HCI_FILTER? -
socket.HCI_TIME_STAMP? -
socket.HCI_DATA_DIR? 與
BTPROTO_HCI一起使用。HCI_FILTER在 NetBSD 或 DragonFlyBSD 上不可用。HCI_TIME_STAMP和HCI_DATA_DIR在 FreeBSD、NetBSD 或 DragonFlyBSD 上不可用。
函數(shù)?
創(chuàng)建套接字?
下列函數(shù)都能創(chuàng)建 套接字對(duì)象.
-
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)? 使用給定的地址簇、套接字類型和協(xié)議號(hào)創(chuàng)建一個(gè)新的套接字。地址簇應(yīng)為
AF_INET(默認(rèn))、AF_INET6、AF_UNIX、AF_CAN、AF_PACKET或AF_RDS其中之一。套接字類型應(yīng)為SOCK_STREAM(默認(rèn))、SOCK_DGRAM、SOCK_RAW或其他SOCK_常量之一。協(xié)議號(hào)通常為零,可以省略,或者在地址簇為AF_CAN的情況下,協(xié)議號(hào)應(yīng)為CAN_RAW、CAN_BCM或CAN_ISOTP之一。如果指定了 fileno,那么將從這一指定的文件描述符中自動(dòng)檢測(cè) family、type 和 proto 的值。如果調(diào)用本函數(shù)時(shí)顯式指定了 family、type 或 proto 參數(shù),可以覆蓋自動(dòng)檢測(cè)的值。這只會(huì)影響 Python 表示諸如
socket.getpeername()一類函數(shù)的返回值的方式,而不影響實(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_NONBLOCK或SOCK_CLOEXEC標(biāo)志位應(yīng)用于 type 上時(shí),它們會(huì)被清除,且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)建一個(gè)非阻塞的套接字,但是sock.type會(huì)被置為socket.SOCK_STREAM。
-
socket.socketpair([family[, type[, proto]]])? 構(gòu)建一對(duì)已連接的套接字對(duì)象,使用給定的地址簇、套接字類型和協(xié)議號(hào)。地址簇、套接字類型和協(xié)議號(hào)與上述
socket()函數(shù)相同。默認(rèn)地址簇為AF_UNIX(需要當(dāng)前平臺(tái)支持,不支持則默認(rèn)為AF_INET)。新創(chuàng)建的套接字都是 不可繼承的。
在 3.2 版更改: 現(xiàn)在,返回的套接字對(duì)象支持全部套接字 API,而不是全部 API 的一個(gè)子集。
在 3.4 版更改: 返回的套接字現(xiàn)在都是不可繼承的。
在 3.5 版更改: 添加了 Windows 支持。
-
socket.create_connection(address[, timeout[, source_address]])? 連接到一個(gè) TCP 服務(wù),該服務(wù)正在偵聽 Internet address (用二元組
(host, port)表示)。連接后返回套接字對(duì)象。這是比socket.connect()更高級(jí)的函數(shù):如果 host 是非數(shù)字主機(jī)名,它將嘗試從AF_INET和AF_INET6解析它,然后依次嘗試連接到所有可能的地址,直到連接成功。這使得編寫兼容 IPv4 和 IPv6 的客戶端變得容易。傳入可選參數(shù) timeout 可以在套接字實(shí)例上設(shè)置超時(shí)(在嘗試連接前)。如果未提供 timeout,則使用由
getdefaulttimeout()返回的全局默認(rèn)超時(shí)設(shè)置。如果提供了 source_address,它必須為二元組
(host, port),以便套接字在連接之前綁定為其源地址。如果 host 或 port 分別為 '' 或 0,則使用操作系統(tǒng)默認(rèn)行為。在 3.2 版更改: 添加了*source_address* 參數(shù)
-
socket.fromfd(fd, family, type, proto=0)? 復(fù)制文件描述符 fd (一個(gè)由文件對(duì)象的
fileno()方法返回的整數(shù)),然后從結(jié)果中構(gòu)建一個(gè)套接字對(duì)象。地址簇、套接字類型和協(xié)議號(hào)與上述socket()函數(shù)相同。文件描述符應(yīng)指向一個(gè)套接字,但不會(huì)專門去檢查——如果文件描述符是無效的,則對(duì)該對(duì)象的后續(xù)操作可能會(huì)失敗。本函數(shù)很少用到,但是在將套接字作為標(biāo)準(zhǔn)輸入或輸出傳遞給程序(如 Unix inet 守護(hù)程序啟動(dòng)的服務(wù)器)時(shí),可以使用本函數(shù)獲取或設(shè)置套接字選項(xiàng)。套接字須處于阻塞模式。新創(chuàng)建的套接字是 不可繼承的。
在 3.4 版更改: 返回的套接字現(xiàn)在是不可繼承的。
根據(jù)
socket.share()方法獲得的數(shù)據(jù)實(shí)例化套接字。套接字須處于阻塞模式。可用性: Windows。
3.3 新版功能.
-
socket.SocketType? 這是一個(gè) Python 類型對(duì)象,表示套接字對(duì)象的類型。它等同于
type(socket(...))。
其他功能?
socket 模塊還提供各種與網(wǎng)絡(luò)相關(guān)的服務(wù):
-
socket.close(fd)? 關(guān)閉一個(gè)套接字文件描述符。它類似于
os.close(),但專用于套接字。在某些平臺(tái)上(特別是在 Windows 上),os.close()對(duì)套接字文件描述符無效。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'、端口號(hào)(數(shù)字)或None。傳入None作為 host 和 port 的值,相當(dāng)于將NULL傳遞給底層 C API。可以指定 family、type 和 proto 參數(shù),以縮小返回的地址列表。向這些參數(shù)分別傳入 0 表示保留全部結(jié)果范圍。flags 參數(shù)可以是
AI_*常量中的一個(gè)或多個(gè),它會(huì)影響結(jié)果的計(jì)算和返回。例如,AI_NUMERICHOST會(huì)禁用域名解析,此時(shí)如果 host 是域名,則會(huì)拋出錯(cuò)誤。本函數(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 是一個(gè)表示套接字地址的元組,具體格式取決于返回的 family (對(duì)于AF_INET,是一個(gè)(address, port)二元組,對(duì)于AF_INET6,是一個(gè)(address, port, flow info, scope id)四元組),可以用于傳遞給socket.connect()方法。下面的示例獲取了 TCP 連接地址信息,假設(shè)該連接通過 80 端口連接至
example.org?(如果系統(tǒng)未啟用 IPv6,則結(jié)果可能會(huì)不同):>>> 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 版更改: 對(duì)于 IPv6 多播地址,表示地址的字符串將不包含
%scope部分。
-
socket.getfqdn([name])? 返回 name 的全限定域名 (Fully Qualified Domain Name -- FQDN)。如果 name 省略或?yàn)榭眨瑒t將其解釋為本地主機(jī)。為了查找全限定名稱,首先將檢查由
gethostbyaddr()返回的主機(jī)名,然后是主機(jī)的別名(如果存在)。選中第一個(gè)包含句點(diǎn)的名字。如果無法獲取全限定域名,則返回由gethostname()返回的主機(jī)名。
-
socket.gethostbyname(hostname)? 將主機(jī)名轉(zhuǎn)換為 IPv4 地址格式。IPv4 地址以字符串格式返回,如
'100.50.200.5'。如果主機(jī)名本身是 IPv4 地址,則原樣返回。更完整的接口請(qǐng)參考gethostbyname_ex()。gethostbyname()不支持 IPv6 域名解析,應(yīng)使用getaddrinfo()來支持 IPv4/v6 雙協(xié)議棧。
-
socket.gethostbyname_ex(hostname)? 將主機(jī)名轉(zhuǎn)換為 IPv4 地址格式的擴(kuò)展接口。返回三元組
(hostname, aliaslist, ipaddrlist),其中 hostname 是響應(yīng)給定 ip_address 的主要主機(jī)名,aliaslist 是相同地址的其他可用主機(jī)名的列表(可能為空),而 ipaddrlist 是 IPv4 地址列表,包含相同主機(jī)名、相同接口的不同地址(通常是一個(gè)地址,但不總是如此)。gethostbyname_ex()不支持 IPv6 名稱解析,應(yīng)使用getaddrinfo()來支持 IPv4/v6 雙協(xié)議棧。
-
socket.gethostname()? 返回一個(gè)字符串,包含當(dāng)前正在運(yùn)行 Python 解釋器的機(jī)器的主機(jī)名。
注意:
gethostname()并不總是返回全限定域名,必要的話請(qǐng)使用getfqdn()。
-
socket.gethostbyaddr(ip_address)? 返回三元組
(hostname, aliaslist, ipaddrlist),其中 hostname 是響應(yīng)給定 ip_address 的主要主機(jī)名,aliaslist 是相同地址的其他可用主機(jī)名的列表(可能為空),而 ipaddrlist 是 IPv4/v6 地址列表,包含相同主機(jī)名、相同接口的不同地址(很可能僅包含一個(gè)地址)。要查詢?nèi)薅ㄓ蛎?qǐng)使用函數(shù)getfqdn()。gethostbyaddr()支持 IPv4 和 IPv6。
-
socket.getnameinfo(sockaddr, flags)? 將套接字地址 sockaddr 轉(zhuǎn)換為二元組
(host, port)。host 的形式可能是全限定域名,或是由數(shù)字表示的地址,具體取決于 flags 的設(shè)置。同樣,port 可以包含字符串格式的端口名稱或數(shù)字格式的端口號(hào)。對(duì)于 IPv6 地址,如果 sockaddr 包含有意義的 scopeid,則將
%scope附加到 host 部分。這種情況通常發(fā)生在多播地址上。
-
socket.getprotobyname(protocolname)? 將 Internet 協(xié)議名稱(如
'icmp')轉(zhuǎn)換為常量,該常量適用于socket()函數(shù)的第三個(gè)(可選)參數(shù)。通常只有在 "raw" 模式 (SOCK_RAW) 中打開的套接字才需要使用該常量。對(duì)于正常的套接字模式,協(xié)議省略或?yàn)榱銜r(shí),會(huì)自動(dòng)選擇正確的協(xié)議。
-
socket.getservbyname(servicename[, protocolname])? 將 Internet 服務(wù)名稱和協(xié)議名稱轉(zhuǎn)換為該服務(wù)的端口號(hào)。協(xié)議名稱是可選的,如果提供的話應(yīng)為
'tcp'或'udp',否則將匹配出所有協(xié)議。
-
socket.getservbyport(port[, protocolname])? 將 Internet 端口號(hào)和協(xié)議名稱轉(zhuǎn)換為該服務(wù)的服務(wù)名稱。協(xié)議名稱是可選的,如果提供的話應(yīng)為
'tcp'或'udp',否則將匹配出所有協(xié)議。
-
socket.ntohl(x)? 將 32 位正整數(shù)從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機(jī)字節(jié)序。在主機(jī)字節(jié)序與網(wǎng)絡(luò)字節(jié)序相同的計(jì)算機(jī)上,這是一個(gè)空操作。字節(jié)序不同將執(zhí)行 4 字節(jié)交換操作。
-
socket.ntohs(x)? 將 16 位正整數(shù)從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機(jī)字節(jié)序。在主機(jī)字節(jié)序與網(wǎng)絡(luò)字節(jié)序相同的計(jì)算機(jī)上,這是一個(gè)空操作。字節(jié)序不同將執(zhí)行 2 字節(jié)交換操作。
3.7 版后已移除: 如果 x 不符合 16 位無符號(hào)整數(shù),但符合 C 語言的正整數(shù),則它會(huì)被靜默截?cái)酁?16 位無符號(hào)整數(shù)。此靜默截?cái)喙δ芤褩売茫磥戆姹镜?Python 將對(duì)此拋出異常。
-
socket.htonl(x)? 將 32 位正整數(shù)從主機(jī)字節(jié)序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序。在主機(jī)字節(jié)序與網(wǎng)絡(luò)字節(jié)序相同的計(jì)算機(jī)上,這是一個(gè)空操作。字節(jié)序不同將執(zhí)行 4 字節(jié)交換操作。
-
socket.htons(x)? 將 16 位正整數(shù)從主機(jī)字節(jié)序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序。在主機(jī)字節(jié)序與網(wǎng)絡(luò)字節(jié)序相同的計(jì)算機(jī)上,這是一個(gè)空操作。字節(jié)序不同將執(zhí)行 2 字節(jié)交換操作。
3.7 版后已移除: 如果 x 不符合 16 位無符號(hào)整數(shù),但符合 C 語言的正整數(shù),則它會(huì)被靜默截?cái)酁?16 位無符號(hào)整數(shù)。此靜默截?cái)喙δ芤褩売茫磥戆姹镜?Python 將對(duì)此拋出異常。
-
socket.inet_aton(ip_string)? 將 IPv4 地址從點(diǎn)分十進(jìn)制字符串格式(如 '123.45.67.89' )轉(zhuǎn)換為 32 位壓縮二進(jìn)制格式,轉(zhuǎn)換后為字節(jié)對(duì)象,長(zhǎng)度為四個(gè)字符。與那些使用標(biāo)準(zhǔn) C 庫,且需要
struct in_addr類型的對(duì)象的程序交換信息時(shí),此功能很有用。 該類型即此函數(shù)返回的 32 位壓縮二進(jìn)制的 C 類型。inet_aton()也接受句點(diǎn)數(shù)少于三的字符串,詳情請(qǐng)參閱 Unix 手冊(cè) inet(3)。如果傳入本函數(shù)的 IPv4 地址字符串無效,則拋出
OSError。注意,具體什么樣的地址有效取決于inet_aton()的底層 C 實(shí)現(xiàn)。inet_aton()不支持 IPv6,在 IPv4/v6 雙協(xié)議棧下應(yīng)使用inet_pton()來代替。
-
socket.inet_ntoa(packed_ip)? 將 32 位壓縮 IPv4 地址(一個(gè) 類字節(jié)對(duì)象,長(zhǎng) 4 個(gè)字節(jié))轉(zhuǎn)換為標(biāo)準(zhǔn)的點(diǎn)分十進(jìn)制字符串形式(如 '123.45.67.89' )。與那些使用標(biāo)準(zhǔn) C 庫,且需要
struct in_addr類型的對(duì)象的程序交換信息時(shí),本函數(shù)很有用。 該類型即本函數(shù)參數(shù)中的 32 位壓縮二進(jìn)制數(shù)據(jù)的 C 類型。如果傳入本函數(shù)的字節(jié)序列長(zhǎng)度不是 4 個(gè)字節(jié),則拋出
OSError。inet_ntoa()不支持 IPv6,在 IPv4/v6 雙協(xié)議棧下應(yīng)使用inet_ntop()來代替。在 3.5 版更改: 現(xiàn)在支持可寫的 字節(jié)類對(duì)象。
-
socket.inet_pton(address_family, ip_string)? 將特定地址簇的 IP 地址(字符串)轉(zhuǎn)換為壓縮二進(jìn)制格式。當(dāng)庫或網(wǎng)絡(luò)協(xié)議需要接受
struct in_addr類型的對(duì)象(類似inet_aton())或struct in6_addr類型的對(duì)象時(shí),inet_pton()很有用。目前 address_family 支持
AF_INET和AF_INET6。如果 IP 地址字符串 ip_string 無效,則拋出OSError。注意,具體什么地址有效取決于 address_family 的值和inet_pton()的底層實(shí)現(xiàn)。可用性: Unix(可能非所有平臺(tái)都可用)、Windows。
在 3.4 版更改: 添加了 Windows 支持
-
socket.inet_ntop(address_family, packed_ip)? 將壓縮 IP 地址(一個(gè) 類字節(jié)對(duì)象,數(shù)個(gè)字節(jié)長(zhǎng))轉(zhuǎn)換為標(biāo)準(zhǔn)的、特定地址簇的字符串形式(如
'7.10.0.5'或'5aef:2b::8')。當(dāng)庫或網(wǎng)絡(luò)協(xié)議返回struct in_addr類型的對(duì)象(類似inet_ntoa())或struct in6_addr類型的對(duì)象時(shí),inet_ntop()很有用。目前 address_family 支持
AF_INET和AF_INET6。如果字節(jié)對(duì)象 packed_ip 與指定的地址簇長(zhǎng)度不符,則拋出ValueError。針對(duì)inet_ntop()調(diào)用的錯(cuò)誤則拋出OSError。可用性: Unix(可能非所有平臺(tái)都可用)、Windows。
在 3.4 版更改: 添加了 Windows 支持
在 3.5 版更改: 現(xiàn)在支持可寫的 字節(jié)類對(duì)象。
-
socket.CMSG_LEN(length)? 返回給定 length 所關(guān)聯(lián)數(shù)據(jù)的輔助數(shù)據(jù)項(xiàng)的總長(zhǎng)度(不帶尾部填充)。此值通常用作
recvmsg()接收一個(gè)輔助數(shù)據(jù)項(xiàng)的緩沖區(qū)大小,但是 RFC 3542 要求可移植應(yīng)用程序使用CMSG_SPACE(),以此將尾部填充的空間計(jì)入,即使該項(xiàng)在緩沖區(qū)的最后。如果 length 超出允許范圍,則拋出OverflowError。可用性: 大多數(shù) Unix 平臺(tái),其他平臺(tái)也可能可用。
3.3 新版功能.
-
socket.CMSG_SPACE(length)? 返回
recvmsg()所需的緩沖區(qū)大小,以接收給定 length 所關(guān)聯(lián)數(shù)據(jù)的輔助數(shù)據(jù)項(xiàng),帶有尾部填充。接收多個(gè)項(xiàng)目所需的緩沖區(qū)空間是關(guān)聯(lián)數(shù)據(jù)長(zhǎng)度的CMSG_SPACE()值的總和。如果 length 超出允許范圍,則拋出OverflowError。請(qǐng)注意,某些系統(tǒng)可能支持輔助數(shù)據(jù),但不提供本函數(shù)。還需注意,如果使用本函數(shù)的結(jié)果來設(shè)置緩沖區(qū)大小,可能無法精確限制可接收的輔助數(shù)據(jù)量,因?yàn)榭赡軙?huì)有其他數(shù)據(jù)寫入尾部填充區(qū)域。
可用性: 大多數(shù) Unix 平臺(tái),其他平臺(tái)也可能可用。
3.3 新版功能.
-
socket.getdefaulttimeout()? 返回用于新套接字對(duì)象的默認(rèn)超時(shí)(以秒為單位的浮點(diǎn)數(shù))。值
None表示新套接字對(duì)象沒有超時(shí)。首次導(dǎo)入 socket 模塊時(shí),默認(rèn)值為None。
-
socket.setdefaulttimeout(timeout)? 設(shè)置用于新套接字對(duì)象的默認(rèn)超時(shí)(以秒為單位的浮點(diǎn)數(shù))。首次導(dǎo)入 socket 模塊時(shí),默認(rèn)值為
None。可能的取值及其各自的含義請(qǐng)參閱settimeout()。
-
socket.sethostname(name)? 將計(jì)算機(jī)的主機(jī)名設(shè)置為 name。如果權(quán)限不足將拋出
OSError。可用性: Unix。
3.3 新版功能.
-
socket.if_nameindex()? 返回一個(gè)列表,包含網(wǎng)絡(luò)接口(網(wǎng)卡)信息二元組(整數(shù)索引,名稱字符串)。系統(tǒng)調(diào)用失敗則拋出
OSError。可用性: Unix。
3.3 新版功能.
套接字對(duì)象?
套接字對(duì)象具有以下方法。除了 makefile(),其他都與套接字專用的 Unix 系統(tǒng)調(diào)用相對(duì)應(yīng)。
-
socket.accept()? 接受一個(gè)連接。此 socket 必須綁定到一個(gè)地址上并且監(jiān)聽連接。返回值是一個(gè)
(conn, address)對(duì),其中 conn 是一個(gè) 新 的套接字對(duì)象,用于在此連接上收發(fā)數(shù)據(jù),address 是連接另一端的套接字所綁定的地址。新創(chuàng)建的套接字是 不可繼承的。
在 3.4 版更改: 該套接字現(xiàn)在是不可繼承的。
在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號(hào)處理程序沒有觸發(fā)異常,此方法現(xiàn)在會(huì)重試系統(tǒng)調(diào)用,而不是觸發(fā)
InterruptedError異常 (原因詳見 PEP 475)。
-
socket.bind(address)? 將套接字綁定到 address。套接字必須尚未綁定。( address 的格式取決于地址簇 —— 參見上文)
-
socket.close()? 將套接字標(biāo)記為關(guān)閉。當(dāng)
makefile()創(chuàng)建的所有文件對(duì)象都關(guān)閉時(shí),底層系統(tǒng)資源(如文件描述符)也將關(guān)閉。一旦上述情況發(fā)生,將來對(duì)套接字對(duì)象的所有操作都會(huì)失敗。對(duì)端將接收不到任何數(shù)據(jù)(清空隊(duì)列數(shù)據(jù)后)。垃圾回收時(shí),套接字會(huì)自動(dòng)關(guān)閉,但建議顯式
close()它們,或在它們周圍使用with語句。在 3.6 版更改: 現(xiàn)在,如果底層的
close()調(diào)用出錯(cuò),會(huì)拋出OSError。注解
close()釋放與連接相關(guān)聯(lián)的資源,但不一定立即關(guān)閉連接。如果需要及時(shí)關(guān)閉連接,請(qǐng)?jiān)谡{(diào)用close()之前調(diào)用shutdown()。
-
socket.connect(address)? 連接到 address 處的遠(yuǎn)程套接字。( address 的格式取決于地址簇 —— 參見上文)
如果連接被信號(hào)中斷,則本方法將等待,直到連接完成。如果信號(hào)處理程序未拋出異常,且套接字阻塞中或已超時(shí),則在超時(shí)后拋出
socket.timeout。對(duì)于非阻塞套接字,如果連接被信號(hào)中斷,則本方法將拋出InterruptedError異常(或信號(hào)處理程序拋出的異常)。在 3.5 版更改: 本方法現(xiàn)在將等待,直到連接完成,而不是在以下情況拋出
InterruptedError異常。該情況為,連接被信號(hào)中斷,信號(hào)處理程序未拋出異常,且套接字阻塞中或已超時(shí)(具體解釋請(qǐng)參閱 PEP 475 )。
-
socket.connect_ex(address)? 類似于
connect(address),但是對(duì)于 C 級(jí)別的connect()調(diào)用返回的錯(cuò)誤,本函數(shù)將返回錯(cuò)誤指示器,而不是拋出異常(對(duì)于其他問題,如“找不到主機(jī)”,仍然可以拋出異常)。如果操作成功,則錯(cuò)誤指示器為0,否則為errno變量的值。這對(duì)支持如異步連接很有用。
-
socket.detach()? 將套接字對(duì)象置于關(guān)閉狀態(tài),而底層的文件描述符實(shí)際并不關(guān)閉。返回該文件描述符,使其可以重新用于其他目的。
3.2 新版功能.
-
socket.fileno()? 返回套接字的文件描述符(一個(gè)小整數(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 套接字的端口號(hào)。(返回的地址格式取決于地址簇 —— 參見上文。)部分系統(tǒng)不支持此函數(shù)。
-
socket.getsockname()? 返回套接字本身的地址。舉例而言,這可以用于查找 IPv4/v6 套接字的端口號(hào)。(返回的地址格式取決于地址簇 —— 參見上文。)
-
socket.getsockopt(level, optname[, buflen])? 返回指定套接字選項(xiàng)的值(參閱 Unix 手冊(cè)頁 getsockopt(2) )。所需的符號(hào)常量(
SO_*等)已定義在本模塊中。如果未指定 buflen,則認(rèn)為該選項(xiàng)值為整數(shù),由本函數(shù)返回該整數(shù)值。如果指定 buflen,則它定義了用于存放選項(xiàng)值的緩沖區(qū)的最大長(zhǎng)度,且該緩沖區(qū)將作為字節(jié)對(duì)象返回。對(duì)緩沖區(qū)的解碼工作由調(diào)用者自行完成(針對(duì)編碼為字節(jié)串的 C 結(jié)構(gòu),其解碼方法請(qǐng)參閱可選的內(nèi)置模塊struct)。
-
socket.getblocking()? 如果套接字處于阻塞模式,返回
True,非阻塞模式返回False。這相當(dāng)于檢測(cè)
socket.gettimeout() == 0。3.7 新版功能.
-
socket.gettimeout()? 返回套接字操作相關(guān)的超時(shí)秒數(shù)(浮點(diǎn)數(shù)),未設(shè)置超時(shí)則返回
None。它反映最后一次調(diào)用setblocking()或settimeout()后的設(shè)置。
-
socket.ioctl(control, option)? - 平臺(tái)
Windows
ioctl()方法是 WSAIoctl 系統(tǒng)接口的有限接口。請(qǐng)參考 Win32 文檔 以獲取更多信息。在其他平臺(tái)上,可以使用通用的
fcntl.fcntl()和fcntl.ioctl()函數(shù),它們接受套接字對(duì)象作為第一個(gè)參數(shù)。當(dāng)前僅支持以下控制碼:
SIO_RCVALL、SIO_KEEPALIVE_VALS和SIO_LOOPBACK_FAST_PATH。在 3.6 版更改: 添加了
SIO_LOOPBACK_FAST_PATH。
-
socket.listen([backlog])? 啟動(dòng)一個(gè)服務(wù)器用于接受連接。如果指定 backlog,則它最低為 0(小于 0 會(huì)被置為 0),它指定系統(tǒng)允許暫未 accept 的連接數(shù),超過后將拒絕新連接。未指定則自動(dòng)設(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)的 文件對(duì)象。返回的對(duì)象的具體類型取決于
makefile()的參數(shù)。這些參數(shù)的解釋方式與內(nèi)置的open()函數(shù)相同,其中 mode 的值僅支持'r'(默認(rèn)),'w'和'b'。套接字必須處于阻塞模式,它可以有超時(shí),但是如果發(fā)生超時(shí),文件對(duì)象的內(nèi)部緩沖區(qū)可能會(huì)以不一致的狀態(tài)結(jié)尾。
關(guān)閉
makefile()返回的文件對(duì)象不會(huì)關(guān)閉原始套接字,除非所有其他文件對(duì)象都已關(guān)閉且在套接字對(duì)象上調(diào)用了socket.close()。注解
在 Windows 上,由
makefile()創(chuàng)建的文件類對(duì)象無法作為帶文件描述符的文件對(duì)象使用,如無法作為subprocess.Popen()的流參數(shù)。
-
socket.recv(bufsize[, flags])? 從套接字接收數(shù)據(jù)。返回值是一個(gè)字節(jié)對(duì)象,表示接收到的數(shù)據(jù)。bufsize 指定一次接收的最大數(shù)據(jù)量。可選參數(shù) flags 的含義請(qǐng)參閱 Unix 手冊(cè)頁 recv(2),它默認(rèn)為零。
注解
為了最佳匹配硬件和網(wǎng)絡(luò)的實(shí)際情況,bufsize 的值應(yīng)為 2 的相對(duì)較小的冪,如 4096。
在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號(hào)處理程序沒有觸發(fā)異常,此方法現(xiàn)在會(huì)重試系統(tǒng)調(diào)用,而不是觸發(fā)
InterruptedError異常 (原因詳見 PEP 475)。
-
socket.recvfrom(bufsize[, flags])? 從套接字接收數(shù)據(jù)。返回值是一對(duì)
(bytes, address),其中 bytes 是字節(jié)對(duì)象,表示接收到的數(shù)據(jù),address 是發(fā)送端套接字的地址。可選參數(shù) flags 的含義請(qǐng)參閱 Unix 手冊(cè)頁 recv(2),它默認(rèn)為零。( address 的格式取決于地址簇 —— 參見上文)在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號(hào)處理程序沒有觸發(fā)異常,此方法現(xiàn)在會(huì)重試系統(tǒng)調(diào)用,而不是觸發(fā)
InterruptedError異常 (原因詳見 PEP 475)。在 3.7 版更改: 對(duì)于多播 IPv6 地址,address 的第一項(xiàng)不再包含
%scope部分。要獲得完整的 IPv6 地址,請(qǐng)使用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()計(jì)算輔助數(shù)據(jù)緩沖區(qū)的合適大小,無法放入緩沖區(qū)的項(xiàng)目可能會(huì)被截?cái)嗷騺G棄。flags 參數(shù)默認(rèn)為 0,其含義與recv()中的相同。返回值是一個(gè)四元組:
(data, ancdata, msg_flags, address)。data 項(xiàng)是一個(gè)bytes對(duì)象,用于保存接收到的非輔助數(shù)據(jù)。ancdata 項(xiàng)是零個(gè)或多個(gè)元組(cmsg_level, cmsg_type, cmsg_data)組成的列表,表示接收到的輔助數(shù)據(jù)(控制消息):cmsg_level 和 cmsg_type 是分別表示協(xié)議級(jí)別和協(xié)議類型的整數(shù),而 cmsg_data 是保存相關(guān)數(shù)據(jù)的bytes對(duì)象。msg_flags 項(xiàng)由各種標(biāo)志按位或組成,表示接收消息的情況,詳細(xì)信息請(qǐng)參閱系統(tǒng)文檔。如果接收端套接字?jǐn)嚅_連接,則 address 是發(fā)送端套接字的地址(如果有),否則該值無指定。某些系統(tǒng)上可以利用
AF_UNIX套接字通過sendmsg()和recvmsg()在進(jìn)程之間傳遞文件描述符。使用此功能時(shí)(通常僅限于SOCK_STREAM套接字),recvmsg()將在其輔助數(shù)據(jù)中返回以下格式的項(xiàng)(socket.SOL_SOCKET, socket.SCM_RIGHTS, fds),其中 fds 是一個(gè)bytes對(duì)象,是新文件描述符表示為原生 Cint類型的二進(jìn)制數(shù)組。如果recvmsg()在系統(tǒng)調(diào)用返回后拋出異常,它將首先關(guān)閉此機(jī)制接收到的所有文件描述符。對(duì)于僅接收到一部分的輔助數(shù)據(jù)項(xiàng),一些系統(tǒng)沒有指示其截?cái)嚅L(zhǎng)度。如果某個(gè)項(xiàng)目可能超出了緩沖區(qū)的末尾,
recvmsg()將發(fā)出RuntimeWarning,并返回其在緩沖區(qū)內(nèi)的部分,前提是該對(duì)象被截?cái)嘤陉P(guān)聯(lián)數(shù)據(jù)開始后。在支持
SCM_RIGHTS機(jī)制的系統(tǒng)上,下方的函數(shù)將最多接收 maxfds 個(gè)文件描述符,返回消息數(shù)據(jù)和包含描述符的列表(同時(shí)忽略意外情況,如接收到無關(guān)的控制消息)。另請(qǐng)參閱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 平臺(tái),其他平臺(tái)也可能可用。
3.3 新版功能.
在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號(hào)處理程序沒有觸發(fā)異常,此方法現(xiàn)在會(huì)重試系統(tǒng)調(diào)用,而不是觸發(fā)
InterruptedError異常 (原因詳見 PEP 475)。
-
socket.recvmsg_into(buffers[, ancbufsize[, flags]])? 從套接字接收普通數(shù)據(jù)和輔助數(shù)據(jù),其行為與
recvmsg()相同,但將非輔助數(shù)據(jù)分散到一系列緩沖區(qū)中,而不是返回新的字節(jié)對(duì)象。buffers 參數(shù)必須是可迭代對(duì)象,它迭代出可供寫入的緩沖區(qū)(如bytearray對(duì)象),這些緩沖區(qū)將被連續(xù)的非輔助數(shù)據(jù)塊填充,直到數(shù)據(jù)全部寫完或緩沖區(qū)用完為止。在允許使用的緩沖區(qū)數(shù)量上,操作系統(tǒng)可能會(huì)有限制(sysconf()的SC_IOV_MAX值)。ancbufsize 和 flags 參數(shù)的含義與recvmsg()中的相同。返回值為四元組:
(nbytes, ancdata, msg_flags, address),其中 nbytes 是寫入緩沖區(qū)的非輔助數(shù)據(jù)的字節(jié)總數(shù),而 ancdata、msg_flags 和 address 與recvmsg()中的相同。示例:
>>> import socket >>> s1, s2 = socket.socketpair() >>> b1 = bytearray(b'----') >>> b2 = bytearray(b'0123456789') >>> b3 = bytearray(b'--------------') >>> s1.send(b'Mary had a little lamb') 22 >>> s2.recvmsg_into([b1, memoryview(b2)[2:9], b3]) (22, [], 0, None) >>> [b1, b2, b3] [bytearray(b'Mary'), bytearray(b'01 had a 9'), bytearray(b'little lamb---')]
可用性: 大多數(shù) Unix 平臺(tái),其他平臺(tái)也可能可用。
3.3 新版功能.
-
socket.recvfrom_into(buffer[, nbytes[, flags]])? 從套接字接收數(shù)據(jù),將其寫入 buffer 而不是創(chuàng)建新的字節(jié)串。返回值是一對(duì)
(nbytes, address),其中 nbytes 是收到的字節(jié)數(shù),address 是發(fā)送端套接字的地址。可選參數(shù) flags 的含義請(qǐng)參閱 Unix 手冊(cè)頁 recv(2),它默認(rèn)為零。( address 的格式取決于地址簇 —— 參見上文)
-
socket.recv_into(buffer[, nbytes[, flags]])? 從套接字接收至多 nbytes 個(gè)字節(jié),將其寫入緩沖區(qū)而不是創(chuàng)建新的字節(jié)串。如果 nbytes 未指定(或指定為 0),則接收至所給緩沖區(qū)的最大可用大小。返回接收到的字節(jié)數(shù)。可選參數(shù) flags 的含義請(qǐng)參閱 Unix 手冊(cè)頁 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)該主題的更多信息,請(qǐng)參考 套接字編程指南。在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號(hào)處理程序沒有觸發(fā)異常,此方法現(xiàn)在會(huì)重試系統(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ā)生錯(cuò)誤為止。成功后會(huì)返回None。出錯(cuò)后會(huì)拋出一個(gè)異常,此時(shí)并沒有辦法確定成功發(fā)送了多少數(shù)據(jù)。在 3.5 版更改: 每次成功發(fā)送數(shù)據(jù)后,套接字超時(shí)不再重置。現(xiàn)在,套接字超時(shí)是發(fā)送所有數(shù)據(jù)的最大總持續(xù)時(shí)間。
在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號(hào)處理程序沒有觸發(fā)異常,此方法現(xiàn)在會(huì)重試系統(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)套接字。可選參數(shù) flags 的含義與上述
recv()中的相同。本方法返回已發(fā)送的字節(jié)數(shù)。( address 的格式取決于地址簇 —— 參見上文。)在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號(hào)處理程序沒有觸發(fā)異常,此方法現(xiàn)在會(huì)重試系統(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é)類對(duì)象 (如
bytes對(duì)象),在允許使用的緩沖區(qū)數(shù)量上,操作系統(tǒng)可能會(huì)有限制(sysconf()的SC_IOV_MAX值)。ancdata 參數(shù)指定的輔助數(shù)據(jù)(控制消息)應(yīng)為可迭代對(duì)象,迭代出零個(gè)或多個(gè)(cmsg_level, cmsg_type, cmsg_data)元組,其中 cmsg_level 和 cmsg_type 是分別指定協(xié)議級(jí)別和協(xié)議類型的整數(shù),而 cmsg_data 是保存相關(guān)數(shù)據(jù)的字節(jié)類對(duì)象。請(qǐng)注意,某些系統(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ù)通過一個(gè)AF_UNIX套接字來發(fā)送文件描述符列表 fds。另請(qǐng)參閱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 平臺(tái),其他平臺(tái)也可能可用。
3.3 新版功能.
在 3.5 版更改: 如果系統(tǒng)調(diào)用被中斷,但信號(hào)處理程序沒有觸發(fā)異常,此方法現(xiàn)在會(huì)重試系統(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ù)的長(zhǎng)度和標(biāo)志位。可用性: Linux >= 2.6.38。
3.6 新版功能.
-
socket.sendfile(file, offset=0, count=None)? 使用高性能的
os.sendfile發(fā)送文件,直到達(dá)到文件的 EOF 為止,返回已發(fā)送的字節(jié)總數(shù)。file 必須是一個(gè)以二進(jìn)制模式打開的常規(guī)文件對(duì)象。如果os.sendfile不可用(如 Windows)或 file 不是常規(guī)文件,將使用send()代替。offset 指示從哪里開始讀取文件。如果指定了 count,它確定了要發(fā)送的字節(jié)總數(shù),而不會(huì)持續(xù)發(fā)送直到達(dá)到文件的 EOF。返回時(shí)或發(fā)生錯(cuò)誤時(shí),文件位置將更新,在這種情況下,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)用的簡(jiǎn)寫:sock.setblocking(True)相當(dāng)于sock.settimeout(None)sock.setblocking(False)相當(dāng)于sock.settimeout(0.0)
在 3.7 版更改: 本方法不再對(duì)
socket.type屬性設(shè)置SOCK_NONBLOCK標(biāo)志。
-
socket.settimeout(value)? 為阻塞套接字的操作設(shè)置超時(shí)。value 參數(shù)可以是非負(fù)浮點(diǎn)數(shù),表示秒,也可以是
None。如果賦為一個(gè)非零值,那么如果在操作完成前超過了超時(shí)時(shí)間 value,后續(xù)的套接字操作將拋出timeout異常。如果賦為 0,則套接字將處于非阻塞模式。如果指定為None,則套接字將處于阻塞模式。更多信息請(qǐng)查閱 關(guān)于套接字超時(shí)的說明。
在 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è)置給定套接字選項(xiàng)的值(參閱 Unix 手冊(cè)頁 setsockopt(2) )。所需的符號(hào)常量(
SO_*等)已定義在本socket模塊中。該值可以是整數(shù)、None或表示緩沖區(qū)的 字節(jié)類對(duì)象。在后一種情況下,由調(diào)用者確保字節(jié)串中包含正確的數(shù)據(jù)位(關(guān)于將 C 結(jié)構(gòu)體編碼為字節(jié)串的方法,請(qǐng)參閱可選的內(nèi)置模塊struct)。當(dāng) value 設(shè)置為None時(shí),必須設(shè)置 optlen 參數(shù)。這相當(dāng)于調(diào)用setsockopt()C 函數(shù)時(shí)使用了optval=NULL和optlen=optlen參數(shù)。在 3.5 版更改: 現(xiàn)在支持可寫的 字節(jié)類對(duì)象。
在 3.6 版更改: 添加了 setsockopt(level, optname, None, optlen: int) 調(diào)用形式。
-
socket.shutdown(how)? 關(guān)閉一半或全部的連接。如果 how 為
SHUT_RD,則后續(xù)不再允許接收。如果 how 為SHUT_WR,則后續(xù)不再允許發(fā)送。如果 how 為SHUT_RDWR,則后續(xù)的發(fā)送和接收都不允許。
復(fù)制套接字,并準(zhǔn)備將其與目標(biāo)進(jìn)程共享。目標(biāo)進(jìn)程必須以 process_id 形式提供。然后可以利用某種形式的進(jìn)程間通信,將返回的字節(jié)對(duì)象傳遞給目標(biāo)進(jìn)程,還可以使用
fromshare()在新進(jìn)程中重新創(chuàng)建套接字。一旦本方法調(diào)用完畢,就可以安全地將套接字關(guān)閉,因?yàn)椴僮飨到y(tǒng)已經(jīng)為目標(biāo)進(jìn)程復(fù)制了該套接字。可用性: Windows。
3.3 新版功能.
注意此處沒有 read() 或 write() 方法,請(qǐng)使用不帶 flags 參數(shù)的 recv() 和 send() 來替代。
套接字對(duì)象還具有以下(只讀)屬性,這些屬性與傳入 socket 構(gòu)造函數(shù)的值相對(duì)應(yīng)。
-
socket.family? 套接字的協(xié)議簇
-
socket.type? 套接字的類型
-
socket.proto? 套接字的協(xié)議。
關(guān)于套接字超時(shí)的說明?
一個(gè)套接字對(duì)象可以處于以下三種模式之一:阻塞、非阻塞或超時(shí)。套接字默認(rèn)以阻塞模式創(chuàng)建,但是可以調(diào)用 setdefaulttimeout() 來更改。
在 blocking mode (阻塞模式)中,操作將阻塞,直到操作完成或系統(tǒng)返回錯(cuò)誤(如連接超時(shí))。
在 non-blocking mode (非阻塞模式)中,如果操作無法立即完成,則操作將失敗(不幸的是,不同系統(tǒng)返回的錯(cuò)誤不同):位于
select中的函數(shù)可用于了解套接字何時(shí)以及是否可以讀取或?qū)懭搿?/p>在 timeout mode (超時(shí)模式)下,如果無法在指定的超時(shí)內(nèi)完成操作(拋出
timeout異常),或如果系統(tǒng)返回錯(cuò)誤,則操作將失敗。
注解
在操作系統(tǒng)層面上,超時(shí)模式 下的套接字在內(nèi)部都設(shè)置為非阻塞模式。同時(shí),阻塞和超時(shí)模式在文件描述符和套接字對(duì)象之間共享,這些描述符和對(duì)象均應(yīng)指向同一個(gè)網(wǎng)絡(luò)端點(diǎn)。如果,比如你決定使用套接字的 fileno(),這一實(shí)現(xiàn)細(xì)節(jié)可能導(dǎo)致明顯的結(jié)果。
超時(shí)與 connect 方法?
connect() 操作也受超時(shí)設(shè)置的約束,通常建議在調(diào)用 connect() 之前調(diào)用 settimeout(),或?qū)⒊瑫r(shí)參數(shù)直接傳遞給 create_connection()。但是,無論 Python 套接字超時(shí)設(shè)置如何,系統(tǒng)網(wǎng)絡(luò)棧都有可能返回自帶的連接超時(shí)錯(cuò)誤。
示例?
以下是 4 個(gè)使用 TCP/IP 協(xié)議的最小示例程序:一臺(tái)服務(wù)器,它將收到的所有數(shù)據(jù)原樣返回(僅服務(wù)于一個(gè)客戶端),還有一個(gè)使用該服務(wù)器的客戶端。注意,服務(wù)器必須按序執(zhí)行 socket(), bind(), listen(), accept() (可能需要重復(fù)執(zhí)行 accept() 以服務(wù)多個(gè)客戶端),而客戶端僅需要按序執(zhí)行 socket(), connect()。還須注意,服務(wù)器不在偵聽套接字上發(fā)送 sendall()/recv(),而是在 accept() 返回的新套接字上發(fā)送。
前兩個(gè)示例僅支持 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))
下兩個(gè)例子與上兩個(gè)很像,但是同時(shí)支持 IPv4 和 IPv6。 服務(wù)端將監(jiān)聽第一個(gè)可用的地址族(它本應(yīng)同時(shí)監(jiān)聽兩個(gè))。 在大多數(shù)支持 IPv6 的系統(tǒng)上,IPv6 將有優(yōu)先權(quán)并且服務(wù)端可能不會(huì)接受 IPv4 流量。 客戶端將嘗試連接到作為名稱解析結(jié)果被返回的所有地址,并將流量發(fā)送給連接成功的第一個(gè)地址。
# 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 上使用原始套接字編寫一個(gè)非常簡(jiǎn)單的網(wǎng)絡(luò)嗅探器。 這個(gè)例子需要管理員權(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,則要用以下方式打開一個(gè) socket:
socket.socket(socket.AF_CAN, socket.SOCK_DGRAM, socket.CAN_BCM)
在綁定 (CAN_RAW) 或連接 (CAN_BCM) socket 之后,你將可以在 socket 對(duì)象上正常使用 socket.send() 以及 socket.recv() 操作(及同類操作)。
最后一個(gè)例子可能需要特別的權(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')
如果多次運(yùn)行示例,且兩次運(yùn)行間隔很短,可能引發(fā)此錯(cuò)誤:
OSError: [Errno 98] Address already in use
這是因?yàn)榍耙淮芜\(yùn)行使套接字處于 TIME_WAIT 狀態(tài),無法立即重用。
要防止這種情況,需要設(shè)置一個(gè) 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)的本地套接字重新使用,而不必等到固有的超時(shí)到期。
參見
關(guān)于套接字編程(C 語言)的介紹,請(qǐng)參閱以下文章:
An Introductory 4.3BSD Interprocess Communication Tutorial,作者 Stuart Sechrest
An Advanced 4.3BSD Interprocess Communication Tutorial,作者 Samuel J. Leffler et al,
兩篇文章都在 UNIX 開發(fā)者手冊(cè),補(bǔ)充文檔 1(第 PS1:7 和 PS1:8 節(jié))中。那些特定于平臺(tái)的參考資料,它們包含與套接字有關(guān)的各種系統(tǒng)調(diào)用,也是套接字語義細(xì)節(jié)的寶貴信息來源。對(duì)于 Unix,請(qǐng)參考手冊(cè)頁。對(duì)于 Windows,請(qǐng)參閱 WinSock(或 Winsock 2)規(guī)范。如果需要支持 IPv6 的 API,讀者可能希望參考 RFC 3493,標(biāo)題為 Basic Socket Interface Extensions for IPv6。
