socket — 低級別網路介面

原始碼: Lib/socket.py


此模組提供對 BSD socket 介面的訪問。它在所有現代 Unix 系統、Windows、MacOS 以及可能更多的平臺上都可用。

備註

由於呼叫的是作業系統套接字 API,某些行為可能與平臺相關。

可用性:非 WASI。

此模組在 WebAssembly 上不起作用或不可用。有關更多資訊,請參閱 WebAssembly 平臺

Python 介面是 Unix 系統呼叫和套接字型檔介面到 Python 面向物件風格的直接轉譯:socket() 函式返回一個 套接字物件,其方法實現了各種套接字系統呼叫。引數型別比 C 介面更高階:與 Python 檔案上的 read()write() 操作一樣,接收操作中的緩衝區分配是自動的,傳送操作中的緩衝區長度是隱式的。

參見

模組 socketserver

簡化網路伺服器編寫的類。

模組 ssl

套接字物件的 TLS/SSL 封裝。

套接字家族

根據系統和構建選項,此模組支援各種套接字家族。

特定套接字物件所需的地址格式會根據建立套接字物件時指定的地址家族自動選擇。套接字地址表示如下:

  • 繫結到檔案系統節點的 AF_UNIX 套接字的地址表示為字串,使用檔案系統編碼和 'surrogateescape' 錯誤處理程式(參見 PEP 383)。Linux 抽象名稱空間中的地址作為 bytes-like object 返回,帶有一個初始的空位元組;請注意,此名稱空間中的套接字可以與普通檔案系統套接字通訊,因此旨在在 Linux 上執行的程式可能需要處理兩種型別的地址。在作為引數傳遞時,字串或 bytes-like object 可用於任一型別的地址。

    3.3 版本中的變化: 以前,AF_UNIX 套接字路徑假定使用 UTF-8 編碼。

    3.5 版本中修改: 現在接受可寫 bytes-like object

  • 對於 AF_INET 地址家族,使用一對 (host, port),其中 host 是一個字串,表示網際網路域名錶示法中的主機名(例如 'daring.cwi.nl')或一個 IPv4 地址(例如 '100.50.200.5'),而 port 是一個整數。

    • 對於 IPv4 地址,除了主機地址外,還接受兩種特殊形式:'' 表示 INADDR_ANY,用於繫結到所有介面;字串 '<broadcast>' 表示 INADDR_BROADCAST。此行為與 IPv6 不相容,因此,如果您打算在 Python 程式中支援 IPv6,則可能需要避免使用它們。

  • 對於 AF_INET6 地址家族,使用一個四元組 (host, port, flowinfo, scope_id),其中 flowinfoscope_id 表示 C 語言中 struct sockaddr_in6sin6_flowinfosin6_scope_id 成員。對於 socket 模組方法,為了向後相容,可以省略 flowinfoscope_id。但請注意,省略 scope_id 可能會在操作範圍內的 IPv6 地址時導致問題。

    3.7 版本中的變化: 對於多播地址(scope_id 有意義),address 不得包含 %scope_id(或 zone id)部分。此資訊是多餘的,可以安全地省略(推薦)。

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

  • 使用 AF_TIPC 地址家族,Linux 僅支援 TIPC。TIPC 是一種開放的、非基於 IP 的網路協議,設計用於叢集計算機環境。地址由元組表示,欄位取決於地址型別。一般元組形式為 (addr_type, v1, v2, v3 [, scope]),其中

    • addr_typeTIPC_ADDR_NAMESEQTIPC_ADDR_NAMETIPC_ADDR_ID 之一。

    • scopeTIPC_ZONE_SCOPETIPC_CLUSTER_SCOPETIPC_NODE_SCOPE 之一。

    • 如果 addr_typeTIPC_ADDR_NAME,則 v1 是伺服器型別,v2 是埠識別符號,v3 應該為 0。

      如果 addr_typeTIPC_ADDR_NAMESEQ,則 v1 是伺服器型別,v2 是低埠號,v3 是高階口號。

      如果 addr_typeTIPC_ADDR_ID,則 v1 是節點,v2 是引用,v3 應該設定為 0。

  • 對於 AF_CAN 地址家族,使用元組 (interface, ),其中 interface 是一個字串,表示網路介面名稱,例如 'can0'。網路介面名稱 '' 可用於從該家族的所有網路介面接收資料包。

    • CAN_ISOTP 協議需要一個元組 (interface, rx_addr, tx_addr),其中兩個附加引數都是表示 CAN 識別符號(標準或擴充套件)的無符號長整數。

    • CAN_J1939 協議需要一個元組 (interface, name, pgn, addr),其中附加引數是一個表示 ECU 名稱的 64 位無符號整數、一個表示引數組號 (PGN) 的 32 位無符號整數和一個表示地址的 8 位整數。

  • 對於 PF_SYSTEM 家族的 SYSPROTO_CONTROL 協議,使用字串或元組 (id, unit)。字串是使用動態分配 ID 的核心控制的名稱。如果已知核心控制的 ID 和單元號,或者使用已註冊的 ID,則可以使用該元組。

    在 3.3 版本加入。

  • AF_BLUETOOTH 支援以下協議和地址格式

    • BTPROTO_L2CAP 接受一個元組 (bdaddr, psm[, cid[, bdaddr_type]]),其中

      • bdaddr 是一個指定藍牙地址的字串。

      • psm 是一個指定協議/服務複用器的整數。

      • cid 是一個可選的整數,指定通道識別符號。如果未給出,則預設為零。

      • bdaddr_type 是一個可選的整數,指定地址型別;可以是 BDADDR_BREDR(預設)、BDADDR_LE_PUBLICBDADDR_LE_RANDOM 之一。

      3.14 版本中的變化: 添加了 cidbdaddr_type 欄位。

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

    • BTPROTO_HCI 接受的格式取決於您的作業系統。

      • 在 Linux 上,它接受一個整數 device_id 或一個元組 (device_id, [channel]),其中 device_id 指定藍牙裝置的編號,channel 是一個可選的整數,指定 HCI 通道(預設為 HCI_CHANNEL_RAW)。

      • 在 FreeBSD、NetBSD 和 DragonFly BSD 上,它接受 bdaddr,其中 bdaddr 是作為字串的藍牙地址。

      3.2 版本中的變化: 添加了 NetBSD 和 DragonFlyBSD 支援。

      3.13.3 版本中的變化: 添加了 FreeBSD 支援。

      3.14 版本中的變化: 添加了 channel 欄位。現在接受未打包在元組中的 device_id

    • BTPROTO_SCO 接受 bdaddr,其中 bdaddr 是作為字串或 bytes 物件的藍牙地址。(例如 '12:23:34:45:56:67'b'12:23:34:45:56:67'

      3.14 版本中的變化: 添加了 FreeBSD 支援。

  • AF_ALG 是一個僅限 Linux 的基於套接字的核心加密介面。演算法套接字使用包含兩到四個元素的元組 (type, name [, feat [, mask]]) 進行配置,其中

    • type 是演算法型別字串,例如 aeadhashskcipherrng

    • name 是演算法名稱和操作模式字串,例如 sha256hmac(sha256)cbc(aes)drbg_nopr_ctr_aes256

    • featmask 是無符號 32 位整數。

    可用性: Linux >= 2.6.38。

    某些演算法型別需要較新的核心。

    在 3.6 版本加入。

  • AF_VSOCK 允許虛擬機器與其主機之間進行通訊。套接字表示為 (CID, port) 元組,其中上下文 ID 或 CID 和埠是整數。

    可用性: Linux >= 3.9

    參見 vsock(7)

    在 3.7 版本加入。

  • AF_PACKET 是直接連線到網路裝置的低階介面。地址由元組 (ifname, proto[, pkttype[, hatype[, addr]]]) 表示,其中

    • ifname - 指定裝置名稱的字串。

    • proto - 乙太網協議號。可以是 ETH_P_ALL 以捕獲所有協議,也可以是 ETHERTYPE_* 常量 之一或任何其他乙太網協議號。

    • pkttype - 可選整數,指定資料包型別

      • PACKET_HOST (預設) - 傳送給本地主機的包。

      • PACKET_BROADCAST - 物理層廣播包。

      • PACKET_MULTICAST - 傳送給物理層多播地址的包。

      • PACKET_OTHERHOST - 在混雜模式下被裝置驅動程式捕獲的傳送給其他主機的包。

      • PACKET_OUTGOING - 源自本地主機並環回至資料包套接字的包。

    • hatype - 可選整數,指定 ARP 硬體地址型別。

    • addr - 可選的 bytes-like object,指定硬體物理地址,其解釋取決於裝置。

    可用性: Linux >= 2.2。

  • AF_QIPCRTR 是一個僅限 Linux 的基於套接字的介面,用於與高通平臺協處理器上執行的服務進行通訊。地址家族表示為 (node, port) 元組,其中 nodeport 是非負整數。

    可用性: Linux >= 4.7。

    在 3.8 版本加入。

  • IPPROTO_UDPLITE 是 UDP 的一種變體,它允許您指定資料包中由校驗和覆蓋的部分。它添加了兩個可以更改的套接字選項。self.setsockopt(IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV, length) 將更改傳出資料包中由校驗和覆蓋的部分,self.setsockopt(IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV, length) 將過濾掉覆蓋資料過少的資料包。在這兩種情況下,length 應在 range(8, 2**16, 8) 範圍內。

    此類套接字應使用 socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE)(對於 IPv4)或 socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE)(對於 IPv6)來構建。

    可用性: Linux >= 2.6.20, FreeBSD >= 10.1

    在 3.9 版本中新增。

  • AF_HYPERV 是一個僅限 Windows 的基於套接字的介面,用於與 Hyper-V 主機和訪客進行通訊。地址家族表示為 (vm_id, service_id) 元組,其中 vm_idservice_id 是 UUID 字串。

    vm_id 是虛擬機器識別符號,如果目標不是特定的虛擬機器,則為一組已知的 VMID 值。在 socket 上定義的已知 VMID 常量有

    • HV_GUID_ZERO

    • HV_GUID_BROADCAST

    • HV_GUID_WILDCARD - 用於繫結自身並接受來自所有分割槽的連線。

    • HV_GUID_CHILDREN - 用於繫結自身並接受來自子分割槽的連線。

    • HV_GUID_LOOPBACK - 用作自身的目標。

    • HV_GUID_PARENT - 用作繫結時接受來自父分割槽的連線。用作地址目標時,它將連線到父分割槽。

    service_id 是註冊服務的服務識別符號。

    3.12 新版功能.

如果您在 IPv4/v6 套接字地址的 host 部分中使用主機名,程式可能會表現出不確定性行為,因為 Python 使用 DNS 解析返回的第一個地址。套接字地址將根據 DNS 解析結果和/或主機配置解析為不同的實際 IPv4/v6 地址。為了確定性行為,請在 host 部分使用數字地址。

所有錯誤都會引發異常。可能會引發引數型別無效和記憶體不足的常見異常。與套接字或地址語義相關的錯誤會引發 OSError 或其子類之一。

透過 setblocking() 支援非阻塞模式。透過 settimeout() 支援基於超時的泛化。

模組內容

模組 socket 匯出以下元素。

異常

exception socket.error

已棄用的 OSError 別名。

3.3 版本中的變化: 根據 PEP 3151,此類別被設定為 OSError 的別名。

exception socket.herror

OSError 的子類,此異常針對地址相關錯誤引發,即對於在 POSIX C API 中使用 h_errno 的函式,包括 gethostbyname_ex()gethostbyaddr()。伴隨值是一個表示庫呼叫返回錯誤的對 (h_errno, string)h_errno 是一個數值,而 string 表示 h_errno 的描述,由 hstrerror() C 函式返回。

3.3 版本中的變化: 此類別被設定為 OSError 的子類。

exception socket.gaierror

OSError 的子類,此異常由 getaddrinfo()getnameinfo() 針對地址相關錯誤引發。伴隨值是一個表示庫呼叫返回錯誤的對 (error, string)string 表示 error 的描述,由 gai_strerror() C 函式返回。數字 error 值將與此模組中定義的 EAI_* 常量之一匹配。

3.3 版本中的變化: 此類別被設定為 OSError 的子類。

exception socket.timeout

TimeoutError 的已棄用別名。

OSError 的子類,當套接字透過先前呼叫 settimeout()(或透過 setdefaulttimeout() 隱式)啟用了超時併發生超時時,會引發此異常。伴隨值是一個字串,其值目前始終是“timed out”。

3.3 版本中的變化: 此類別被設定為 OSError 的子類。

3.10 版本中的變化: 此類別被設定為 TimeoutError 的別名。

常量

AF_* 和 SOCK_* 常量現在是 AddressFamilySocketKind IntEnum 集合。

在 3.4 版本加入。

socket.AF_UNIX
socket.AF_INET
socket.AF_INET6

這些常量表示地址(和協議)家族,用於 socket() 的第一個引數。如果未定義 AF_UNIX 常量,則表示不支援此協議。根據系統,可能還有更多常量可用。

socket.AF_UNSPEC

AF_UNSPEC 表示 getaddrinfo() 應該返回任何可用的地址家族(IPv4、IPv6 或任何其他)的套接字地址。

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

這些常量表示套接字型別,用於 socket() 的第二個引數。根據系統,可能還有更多常量可用。(只有 SOCK_STREAMSOCK_DGRAM 似乎普遍有用。)

socket.SOCK_CLOEXEC
socket.SOCK_NONBLOCK

這兩個常量,如果已定義,可以與套接字型別結合使用,並允許您原子地設定一些標誌(從而避免可能的競態條件和單獨呼叫的需要)。

參見

安全檔案描述符處理以獲取更詳盡的解釋。

可用性: Linux >= 2.6.27。

在 3.2 版本加入。

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

在 Unix 套接字和/或 IP 協議文件中記錄的許多這些形式的常量也在 socket 模組中定義。它們通常用作套接字物件的 setsockopt()getsockopt() 方法的引數。在大多數情況下,只定義了 Unix 標頭檔案中定義的符號;對於少數符號,提供了預設值。

3.6 版本中的變化: 添加了 SO_DOMAINSO_PROTOCOLSO_PEERSECSO_PASSSECTCP_USER_TIMEOUTTCP_CONGESTION

3.6.5 版本中的變化: 在可用時,添加了對 Windows 平臺上的 TCP_FASTOPENTCP_KEEPCNT 的支援。

3.7 版本中的變化: 添加了 TCP_NOTSENT_LOWAT

在可用時,添加了對 Windows 平臺上的 TCP_KEEPIDLETCP_KEEPINTVL 的支援。

3.10 版本中的變化: 添加了 IP_RECVTOS。添加了 TCP_KEEPALIVE。在 MacOS 上,此常量可以像 Linux 上使用 TCP_KEEPIDLE 一樣使用。

3.11 版本中的變化: 添加了 TCP_CONNECTION_INFO。在 MacOS 上,此常量可以像 Linux 和 BSD 上使用 TCP_INFO 一樣使用。

3.12 版本中的變化: 添加了 SO_RTABLESO_USER_COOKIE。在 OpenBSD 和 FreeBSD 上,這些常量可以分別像 Linux 上使用 SO_MARK 一樣使用。還添加了 Linux 缺少的 TCP 套接字選項:TCP_MD5SIGTCP_THIN_LINEAR_TIMEOUTSTCP_THIN_DUPACKTCP_REPAIRTCP_REPAIR_QUEUETCP_QUEUE_SEQTCP_REPAIR_OPTIONSTCP_TIMESTAMPTCP_CC_INFOTCP_SAVE_SYNTCP_SAVED_SYNTCP_REPAIR_WINDOWTCP_FASTOPEN_CONNECTTCP_ULPTCP_MD5SIG_EXTTCP_FASTOPEN_KEYTCP_FASTOPEN_NO_COOKIETCP_ZEROCOPY_RECEIVETCP_INQTCP_TX_DELAY。添加了 IP_PKTINFOIP_UNBLOCK_SOURCEIP_BLOCK_SOURCEIP_ADD_SOURCE_MEMBERSHIPIP_DROP_SOURCE_MEMBERSHIP

3.13 版本中的變化: 添加了 SO_BINDTOIFINDEX。在 Linux 上,此常量可以像使用 SO_BINDTODEVICE 一樣使用,但使用網路介面的索引而不是其名稱。

3.14 版本中的變化: 在 Linux 上恢復了缺少的 IP_FREEBINDIP_RECVERRIPV6_RECVERRIP_RECVTTLIP_RECVORIGDSTADDR

3.14 版本中的變化: 在可用時,添加了對 Windows 平臺上的 TCP_QUICKACK 的支援。

socket.AF_CAN
socket.PF_CAN
SOL_CAN_*
CAN_*

許多這些形式的常量,在 Linux 文件中記載,也在 socket 模組中定義。

可用性: Linux >= 2.6.25, NetBSD >= 8。

在 3.3 版本加入。

3.11 版本中的變化: 添加了 NetBSD 支援。

3.14 版本中的變化: 恢復了 Linux 上缺少的 CAN_RAW_ERR_FILTER

socket.CAN_BCM
CAN_BCM_*

CAN_BCM,在 CAN 協議家族中,是廣播管理器(BCM)協議。廣播管理器常量,在 Linux 文件中記載,也在 socket 模組中定義。

可用性: Linux >= 2.6.25。

備註

CAN_BCM_CAN_FD_FRAME 標誌僅在 Linux >= 4.8 上可用。

在 3.4 版本加入。

socket.CAN_RAW_FD_FRAMES

在 CAN_RAW 套接字中啟用 CAN FD 支援。此功能預設停用。這允許您的應用程式傳送 CAN 和 CAN FD 幀;但是,在從套接字讀取時,您必須同時接受 CAN 和 CAN FD 幀。

此常量在 Linux 文件中記載。

可用性: Linux >= 3.6。

在 3.5 版本加入。

socket.CAN_RAW_JOIN_FILTERS

連線應用的 CAN 過濾器,以便只有匹配所有給定 CAN 過濾器的 CAN 幀才傳遞到使用者空間。

此常量在 Linux 文件中記載。

可用性: Linux >= 4.1。

在 3.9 版本中新增。

socket.CAN_ISOTP

CAN_ISOTP,在 CAN 協議家族中,是 ISO-TP (ISO 15765-2) 協議。ISO-TP 常量,在 Linux 文件中記載。

可用性: Linux >= 2.6.25。

在 3.7 版本加入。

socket.CAN_J1939

CAN_J1939,在 CAN 協議家族中,是 SAE J1939 協議。J1939 常量,在 Linux 文件中記載。

可用性: Linux >= 5.4。

在 3.9 版本中新增。

socket.AF_DIVERT
socket.PF_DIVERT

這兩個常量,在 FreeBSD divert(4) 手冊頁中記載,也在 socket 模組中定義。

可用性: FreeBSD >= 14.0。

3.12 新版功能.

socket.AF_PACKET
socket.PF_PACKET
PACKET_*

許多這些形式的常量,在 Linux 文件中記載,也在 socket 模組中定義。

可用性: Linux >= 2.2。

socket.ETH_P_ALL

ETH_P_ALL 可用於 socket 建構函式中,作為 AF_PACKET 家族的 proto 引數,以捕獲所有資料包,無論協議如何。

更多資訊,請參閱 packet(7) 手冊頁。

可用性: Linux。

3.12 新版功能.

socket.AF_RDS
socket.PF_RDS
socket.SOL_RDS
RDS_*

許多這些形式的常量,在 Linux 文件中記載,也在 socket 模組中定義。

可用性: Linux >= 2.6.30。

在 3.3 版本加入。

socket.SIO_RCVALL
socket.SIO_KEEPALIVE_VALS
socket.SIO_LOOPBACK_FAST_PATH
RCVALL_*

Windows WSAIoctl() 的常量。這些常量用作套接字物件的 ioctl() 方法的引數。

3.6 版本中的變化: 添加了 SIO_LOOPBACK_FAST_PATH

TIPC_*

TIPC 相關常量,與 C 套接字 API 匯出的常量匹配。有關更多資訊,請參閱 TIPC 文件。

socket.AF_ALG
socket.SOL_ALG
ALG_*

Linux 核心加密的常量。

可用性: 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, macOS。

在 3.4 版本加入。

socket.has_ipv6

此常量包含一個布林值,表示此平臺上是否支援 IPv6。

socket.AF_BLUETOOTH
socket.BTPROTO_L2CAP
socket.BTPROTO_RFCOMM
socket.BTPROTO_HCI
socket.BTPROTO_SCO

用於藍牙地址的整數常量。

socket.BDADDR_ANY
socket.BDADDR_LOCAL

這些是包含特殊含義的藍牙地址字串常量。例如,BDADDR_ANY 可用於在使用 BTPROTO_RFCOMM 指定繫結套接字時指示任何地址。

socket.BDADDR_BREDR
socket.BDADDR_LE_PUBLIC
socket.BDADDR_LE_RANDOM

這些常量描述了繫結或連線 BTPROTO_L2CAP 套接字時的藍牙地址型別。

可用性: Linux, FreeBSD

在 3.14 版本加入。

socket.SOL_RFCOMM
socket.SOL_L2CAP
socket.SOL_HCI
socket.SOL_SCO
socket.SOL_BLUETOOTH

用於藍牙套接字物件的 setsockopt()getsockopt() 方法的 level 引數。

SOL_BLUETOOTH 僅在 Linux 上可用。如果支援相應的協議,則其他常量可用。

SO_L2CAP_*
socket.L2CAP_LM
L2CAP_LM_*
SO_RFCOMM_*
RFCOMM_LM_*
SO_SCO_*
SO_BTH_*
BT_*

用於藍牙套接字物件的 setsockopt()getsockopt() 方法的 option name 和 value 引數。

BT_*L2CAP_LM 僅在 Linux 上可用。SO_BTH_* 僅在 Windows 上可用。其他常量可能在 Linux 和各種 BSD 平臺上可用。

在 3.14 版本加入。

socket.HCI_FILTER
socket.HCI_TIME_STAMP
socket.HCI_DATA_DIR
socket.SO_HCI_EVT_FILTER
socket.SO_HCI_PKT_FILTER

用於 BTPROTO_HCI 的選項名稱。選項值的可用性和格式取決於平臺。

3.14 版本中的變化: 在 NetBSD 和 DragonFly BSD 上添加了 SO_HCI_EVT_FILTERSO_HCI_PKT_FILTER。在 FreeBSD、NetBSD 和 DragonFly BSD 上添加了 HCI_DATA_DIR

socket.HCI_DEV_NONE

用於建立不特定於單個藍牙介面卡的 HCI 套接字的 device_id 值。

可用性: Linux

在 3.14 版本加入。

socket.HCI_CHANNEL_RAW
socket.HCI_CHANNEL_USER
socket.HCI_CHANNEL_MONITOR
socket.HCI_CHANNEL_CONTROL
socket.HCI_CHANNEL_LOGGING

BTPROTO_HCI 地址中 channel 欄位的可能值。

可用性: Linux

在 3.14 版本加入。

socket.AF_QIPCRTR

高通 IPC 路由器協議的常量,用於與提供遠端處理器的服務通訊。

可用性: Linux >= 4.7。

socket.SCM_CREDS2
socket.LOCAL_CREDS
socket.LOCAL_CREDS_PERSISTENT

LOCAL_CREDS 和 LOCAL_CREDS_PERSISTENT 可用於 SOCK_DGRAM、SOCK_STREAM 套接字,等同於 Linux/DragonFlyBSD 的 SO_PASSCRED,其中 LOCAL_CREDS 在第一次讀取時傳送憑據,LOCAL_CREDS_PERSISTENT 在每次讀取時傳送,SCM_CREDS2 必須用於後者的訊息型別。

在 3.11 版本中新增。

可用性: FreeBSD。

socket.SO_INCOMING_CPU

用於最佳化 CPU 區域性性的常量,與 SO_REUSEPORT 結合使用。

在 3.11 版本中新增。

可用性: Linux >= 3.9

socket.SO_REUSEPORT_LB

用於啟用負載均衡的重複地址和埠繫結的常量。

在 3.14 版本加入。

可用性: FreeBSD >= 12.0

socket.AF_HYPERV
socket.HV_PROTOCOL_RAW
socket.HVSOCKET_CONNECT_TIMEOUT
socket.HVSOCKET_CONNECT_TIMEOUT_MAX
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_PARENT

用於 Windows Hyper-V 套接字進行主機/來賓通訊的常量。

可用性: Windows。

3.12 新版功能.

socket.ETHERTYPE_ARP
socket.ETHERTYPE_IP
socket.ETHERTYPE_IPV6
socket.ETHERTYPE_VLAN

IEEE 802.3 協議號。常量。

可用性:Linux, FreeBSD, macOS。

3.12 新版功能.

socket.SHUT_RD
socket.SHUT_WR
socket.SHUT_RDWR

這些常量被套接字物件的 shutdown() 方法使用。

可用性:非 WASI。

函式

建立套接字

以下函式都建立 套接字物件

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

使用給定的地址族、套接字型別和協議號建立一個新套接字。地址族應為 AF_INET (預設值)、AF_INET6AF_UNIXAF_CANAF_PACKETAF_RDS。套接字型別應為 SOCK_STREAM (預設值)、SOCK_DGRAMSOCK_RAW 或可能是其他 SOCK_ 常量之一。協議號通常為零,可以省略;如果地址族是 AF_CAN,則協議應為 CAN_RAWCAN_BCMCAN_ISOTPCAN_J1939 之一。

如果指定了 *fileno*,則 *family*、*type* 和 *proto* 的值將從指定的檔案描述符自動檢測。可以透過使用顯式 *family*、*type* 或 *proto* 引數呼叫函式來覆蓋自動檢測。這隻會影響 Python 如何表示例如 socket.getpeername() 的返回值,而不是實際的作業系統資源。與 socket.fromfd() 不同,*fileno* 將返回相同的套接字而不是副本。這可能有助於使用 socket.close() 關閉一個分離的套接字。

新建立的套接字是不可繼承的

使用引數 selffamilytypeprotocol 觸發 審計事件 socket.__new__

3.3 版更改: 添加了 AF_CAN 族。添加了 AF_RDS 族。

3.4 版更改: 添加了 CAN_BCM 協議。

3.4 版更改: 返回的套接字現在是不可繼承的。

3.7 版更改: 添加了 CAN_ISOTP 協議。

3.7 版更改: SOCK_NONBLOCKSOCK_CLOEXEC 位標誌應用於 *type* 時,它們會被清除,並且 socket.type 將不會反映它們。它們仍會傳遞給底層的系統 socket() 呼叫。因此,

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

在支援 SOCK_NONBLOCK 的作業系統上仍然會建立一個非阻塞套接字,但 sock.type 將設定為 socket.SOCK_STREAM

3.9 版更改: 添加了 CAN_J1939 協議。

3.10 版更改: 添加了 IPPROTO_MPTCP 協議。

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

使用給定的地址族、套接字型別和協議號構建一對已連線的套接字物件。地址族、套接字型別和協議號與上述 socket() 函式相同。如果平臺定義了 AF_UNIX,則預設族為 AF_UNIX;否則,預設族為 AF_INET

新建立的套接字是不可繼承的

3.2 版更改: 返回的套接字物件現在支援完整的套接字 API,而不僅僅是子集。

3.4 版更改: 返回的套接字現在是不可繼承的。

3.5 版更改: 增加了對 Windows 的支援。

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

連線到偵聽在網際網路 *address*(一個 2 元組 (host, port))的 TCP 服務,並返回套接字物件。這是一個比 socket.connect() 更高階的函式:如果 *host* 是非數字主機名,它將嘗試為 AF_INETAF_INET6 解析它,然後依次嘗試連線到所有可能的地址,直到連線成功。這使得編寫相容 IPv4 和 IPv6 的客戶端變得容易。

傳入可選的 *timeout* 引數將在嘗試連線之前設定套接字例項的超時。如果未提供 *timeout*,則使用 getdefaulttimeout() 返回的全域性預設超時設定。

如果提供,*source_address* 必須是一個 2 元組 (host, port),用於在連線之前將套接字繫結到其源地址。如果主機或埠分別為 '' 或 0,將使用作業系統預設行為。

當無法建立連線時,會引發異常。預設情況下,它是列表中最後一個地址的異常。如果 *all_errors* 為 True,它是一個 ExceptionGroup,包含所有嘗試的錯誤。

3.2 版更改: 添加了 *source_address*。

3.11 版更改: 添加了 *all_errors*。

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

便捷函式,建立一個繫結到 *address*(一個 2 元組 (host, port))的 TCP 套接字並返回套接字物件。

*family* 應為 AF_INETAF_INET6。*backlog* 是傳遞給 socket.listen() 的佇列大小;如果未指定,將選擇一個合理的預設值。*reuse_port* 決定是否設定 SO_REUSEPORT 套接字選項。

如果 *dualstack_ipv6* 為真,*family* 為 AF_INET6 並且平臺支援它,則套接字將能夠接受 IPv4 和 IPv6 連線,否則它將引發 ValueError。大多數 POSIX 平臺和 Windows 都應該支援此功能。當此功能啟用時,當發生 IPv4 連線時,socket.getpeername() 返回的地址將是表示為 IPv4 對映的 IPv6 地址的 IPv6 地址。如果 *dualstack_ipv6* 為假,它將顯式停用在預設情況下啟用此功能的平臺(例如 Linux)上的此功能。此引數可以與 has_dualstack_ipv6() 結合使用。

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 平臺上,設定了 SO_REUSEADDR 套接字選項,以便立即重用先前繫結到相同 *address* 並處於 TIME_WAIT 狀態的套接字。

在 3.8 版本加入。

socket.has_dualstack_ipv6()

如果平臺支援建立可同時處理 IPv4 和 IPv6 連線的 TCP 套接字,則返回 True

在 3.8 版本加入。

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

複製檔案描述符 *fd* (一個由檔案物件的 fileno() 方法返回的整數) 並從結果構建一個套接字物件。地址族、套接字型別和協議號與上述 socket() 函式相同。檔案描述符應指向一個套接字,但這不會被檢查 —— 如果檔案描述符無效,後續對物件的操作可能會失敗。這個函式很少需要,但可以用於獲取或設定作為標準輸入或輸出傳遞給程式的套接字選項(例如由 Unix inet 守護程序啟動的伺服器)。套接字假定處於阻塞模式。

新建立的套接字是不可繼承的

3.4 版更改: 返回的套接字現在是不可繼承的。

socket.fromshare(data)

socket.share() 方法獲取的資料例項化一個套接字。套接字假定處於阻塞模式。

可用性: Windows。

在 3.3 版本加入。

socket.SocketType

這是一個 Python 型別物件,表示套接字物件型別。它與 type(socket(...)) 相同。

其他函式

socket 模組還提供各種與網路相關的服務。

socket.close(fd)

關閉一個套接字檔案描述符。這類似於 os.close(),但用於套接字。在某些平臺(最顯著的是 Windows)上,os.close() 不適用於套接字檔案描述符。

在 3.7 版本加入。

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

此函式封裝了底層系統的 C 函式 getaddrinfo

將 *host*/*port* 引數轉換為包含建立連線到該服務所需的所有引數的 5 元組序列。*host* 是一個域名、IPv4/v6 地址的字串表示或 None。*port* 是一個字串服務名,例如 'http'、一個數字埠號或 None。透過將 *host* 和 *port* 的值設定為 None,可以將 NULL 傳遞給底層 C API。

可以可選地指定 *family*、*type* 和 *proto* 引數,以提供選項並限制返回的地址列表。傳入它們的預設值(分別為 AF_UNSPEC、0 和 0)以不限制結果。有關詳細資訊,請參閱下面的註釋。

*flags* 引數可以是一個或多個 AI_* 常量,它將影響結果的計算和返回方式。例如,AI_NUMERICHOST 將停用域名解析,如果 *host* 是域名,則會引發錯誤。

該函式返回一個包含以下結構的 5 元組列表

(family, type, proto, canonname, sockaddr)

在這些元組中,*family*、*type*、*proto* 都是整數,旨在傳遞給 socket() 函式。如果 AI_CANONNAME 是 *flags* 引數的一部分,則 *canonname* 將是一個表示 *host* 規範名稱的字串;否則 *canonname* 將為空。*sockaddr* 是一個描述套接字地址的元組,其格式取決於返回的 *family*(對於 AF_INET(address, port) 2 元組,對於 AF_INET6(address, port, flowinfo, scope_id) 4 元組),旨在傳遞給 socket.connect() 方法。

備註

如果你打算使用 getaddrinfo() 的結果來建立套接字(而不是,例如,檢索 *canonname*),請考慮透過 *type*(例如 SOCK_STREAMSOCK_DGRAM)和/或 *proto*(例如 IPPROTO_TCPIPPROTO_UDP)來限制結果,以使你的應用程式能夠處理。

*family*、*type*、*proto* 和 *flags* 的預設值的行為因系統而異。

許多系統(例如,大多數 Linux 配置)將返回所有匹配地址的排序列表。這些地址通常應按順序嘗試,直到連線成功(可能並行嘗試,例如,使用 Happy Eyeballs 演算法)。在這些情況下,限制 *type* 和/或 *proto* 可以幫助消除不成功或無法使用的連線嘗試。

然而,某些系統只會返回單個地址。(例如,這在 Solaris 和 AIX 配置上有所報道。)在這些系統上,限制 *type* 和/或 *proto* 有助於確保此地址可用。

使用引數 hostportfamilytypeprotocol 觸發 審計事件 socket.getaddrinfo

以下示例獲取了到 example.org 埠 80 的假定 TCP 連線的地址資訊(如果未啟用 IPv6,則系統上的結果可能不同)

>>> 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 版更改: 引數現在可以使用關鍵字引數傳遞。

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

socket.getfqdn([name])

返回 *name* 的完全限定域名。如果 *name* 省略或為空,則將其解釋為本地主機。要查詢完全限定名稱,將檢查 gethostbyaddr() 返回的主機名,然後是主機的別名(如果可用)。選擇第一個包含句點的名稱。如果未提供完全限定域名且提供了 *name*,則返回未更改的名稱。如果 *name* 為空或等於 '0.0.0.0',則返回 gethostname() 的主機名。

socket.gethostbyname(hostname)

將主機名轉換為 IPv4 地址格式。IPv4 地址以字串形式返回,例如 '100.50.200.5'。如果主機名本身就是 IPv4 地址,則不變返回。請參閱 gethostbyname_ex() 以獲取更完整的介面。gethostbyname() 不支援 IPv6 名稱解析,對於 IPv4/v6 雙棧支援,應改用 getaddrinfo()

使用引數 hostname 觸發 審計事件 socket.gethostbyname

可用性:非 WASI。

socket.gethostbyname_ex(hostname)

將主機名轉換為 IPv4 地址格式,擴充套件介面。返回一個 3 元組 (hostname, aliaslist, ipaddrlist),其中 *hostname* 是主機的主要主機名,*aliaslist* 是同一地址的替代主機名列表(可能為空),*ipaddrlist* 是同一主機上同一介面的 IPv4 地址列表(通常但並非總是單個地址)。gethostbyname_ex() 不支援 IPv6 名稱解析,對於 IPv4/v6 雙棧支援,應改用 getaddrinfo()

使用引數 hostname 觸發 審計事件 socket.gethostbyname

可用性:非 WASI。

socket.gethostname()

返回一個包含 Python 直譯器當前正在執行的機器的主機名的字串。

不帶任何引數觸發 審計事件 socket.gethostname

注意:gethostname() 不總是返回完全限定域名;請使用 getfqdn()

可用性:非 WASI。

socket.gethostbyaddr(ip_address)

返回一個 3 元組 (hostname, aliaslist, ipaddrlist),其中 *hostname* 是響應給定 *ip_address* 的主要主機名,*aliaslist* 是同一地址的替代主機名列表(可能為空),*ipaddrlist* 是同一主機上同一介面的 IPv4/v6 地址列表(很可能只包含一個地址)。要查詢完全限定域名,請使用函式 getfqdn()gethostbyaddr() 支援 IPv4 和 IPv6。

使用引數 ip_address 觸發 審計事件 socket.gethostbyaddr

可用性:非 WASI。

socket.getnameinfo(sockaddr, flags)

將套接字地址 *sockaddr* 轉換為 2 元組 (host, port)。根據 *flags* 的設定,結果在 *host* 中可以包含完全限定域名或數字地址表示。同樣,*port* 可以包含字串埠名或數字埠號。

對於 IPv6 地址,如果 *sockaddr* 包含有意義的 *scope_id*,則 %scope_id 會附加到主機部分。通常這發生在組播地址上。

有關 *flags* 的更多資訊,您可以查閱 getnameinfo(3)

使用引數 sockaddr 觸發 審計事件 socket.getnameinfo

可用性:非 WASI。

socket.getprotobyname(protocolname)

將網際網路協議名(例如,'icmp')轉換為適合作為 socket() 函式的(可選)第三個引數傳遞的常量。這通常僅在以“原始”模式(SOCK_RAW)開啟套接字時才需要;對於正常的套接字模式,如果省略協議或協議為零,則會自動選擇正確的協議。

可用性:非 WASI。

socket.getservbyname(servicename[, protocolname])

將網際網路服務名稱和協議名稱轉換為該服務的埠號。可選的協議名稱(如果給出)應為 'tcp''udp',否則任何協議都將匹配。

使用引數 servicename, protocolname 觸發 審計事件 socket.getservbyname

可用性:非 WASI。

socket.getservbyport(port[, protocolname])

將網際網路埠號和協議名稱轉換為該服務的服務名稱。可選的協議名稱(如果給出)應為 'tcp''udp',否則任何協議都將匹配。

使用引數 port, protocolname 觸發 審計事件 socket.getservbyport

可用性:非 WASI。

socket.ntohl(x)

將 32 位正整數從網路位元組序轉換為主機位元組序。在主機位元組序與網路位元組序相同的機器上,這是一個無操作;否則,它執行一個 4 位元組交換操作。

socket.ntohs(x)

將 16 位正整數從網路位元組序轉換為主機位元組序。在主機位元組序與網路位元組序相同的機器上,這是一個無操作;否則,它執行一個 2 位元組交換操作。

3.10 版更改: 如果 *x* 不適合 16 位無符號整數,則引發 OverflowError

socket.htonl(x)

將 32 位正整數從主機位元組序轉換為網路位元組序。在主機位元組序與網路位元組序相同的機器上,這是一個無操作;否則,它執行一個 4 位元組交換操作。

socket.htons(x)

將 16 位正整數從主機位元組序轉換為網路位元組序。在主機位元組序與網路位元組序相同的機器上,這是一個無操作;否則,它執行一個 2 位元組交換操作。

3.10 版更改: 如果 *x* 不適合 16 位無符號整數,則引發 OverflowError

socket.inet_aton(ip_string)

將 IPv4 地址從點分四段字串格式(例如,'123.45.67.89')轉換為 32 位打包二進位制格式,作為長度為四個字元的位元組物件。這在與使用標準 C 庫並需要 in_addr 型別物件的程式通訊時很有用,in_addr 是此函式返回的 32 位打包二進位制的 C 型別。

inet_aton() 也接受少於三個點的字串;有關詳細資訊,請參閱 Unix 手冊頁 inet(3)

如果傳遞給此函式的 IPv4 地址字串無效,將引發 OSError。請注意,具體什麼是有效取決於底層 C 實現的 inet_aton()

inet_aton() 不支援 IPv6,對於 IPv4/v6 雙棧支援,應改用 inet_pton()

socket.inet_ntoa(packed_ip)

將 32 位打包的 IPv4 地址(一個長度為四位元組的類位元組物件)轉換為其標準點分四段字串表示(例如,'123.45.67.89')。這在與使用標準 C 庫並需要 in_addr 型別物件的程式通訊時很有用,in_addr 是此函式作為引數的 32 位打包二進位制資料的 C 型別。

如果傳遞給此函式的位元組序列長度不正好是 4 位元組,將引發 OSErrorinet_ntoa() 不支援 IPv6,對於 IPv4/v6 雙棧支援,應改用 inet_ntop()

3.5 版本中修改: 現在接受可寫 bytes-like object

socket.inet_pton(address_family, ip_string)

將 IP 地址從其家族特定的字串格式轉換為打包的二進位制格式。inet_pton() 在庫或網路協議要求 in_addr 型別物件(類似於 inet_aton())或 in6_addr 時很有用。

目前支援的 *address_family* 值為 AF_INETAF_INET6。如果 IP 地址字串 *ip_string* 無效,將引發 OSError。請注意,具體什麼是有效取決於 *address_family* 的值和 inet_pton() 的底層實現。

可用性: Unix, Windows。

3.4 版更改: 添加了 Windows 支援

socket.inet_ntop(address_family, packed_ip)

將打包的 IP 地址(一個長度為若干位元組的類位元組物件)轉換為其標準的家族特定字串表示(例如,'7.10.0.5''5aef:2b::8')。當庫或網路協議返回 in_addr 型別物件(類似於 inet_ntoa())或 in6_addr 時,inet_ntop() 很有用。

目前支援的 *address_family* 值為 AF_INETAF_INET6。如果位元組物件 *packed_ip* 的長度與指定地址族不符,將引發 ValueErrorinet_ntop() 調用出錯時將引發 OSError

可用性: Unix, Windows。

3.4 版更改: 添加了 Windows 支援

3.5 版本中修改: 現在接受可寫 bytes-like object

socket.CMSG_LEN(length)

返回一個具有給定 *length* 關聯資料的輔助資料項的總長度(不含尾部填充)。這個值通常可用作 recvmsg() 的緩衝區大小,以接收單個輔助資料項,但 RFC 3542 要求可移植應用程式使用 CMSG_SPACE() 並因此包含填充空間,即使該項將是緩衝區中的最後一項。如果 *length* 超出允許的值範圍,則引發 OverflowError

可用性: Unix,不包括 WASI。

大多數 Unix 平臺。

在 3.3 版本加入。

socket.CMSG_SPACE(length)

返回 recvmsg() 接收具有給定 *length* 關聯資料以及任何尾部填充的輔助資料項所需的緩衝區大小。接收多個項所需的緩衝區空間是其關聯資料長度的 CMSG_SPACE() 值之和。如果 *length* 超出允許的值範圍,則引發 OverflowError

請注意,有些系統可能支援輔助資料但未提供此函式。另請注意,使用此函式的結果設定緩衝區大小可能無法精確限制可接收的輔助資料量,因為額外的​​資料可能能夠容納到填充區域中。

可用性: Unix,不包括 WASI。

大多數 Unix 平臺。

在 3.3 版本加入。

socket.getdefaulttimeout()

返回新套接字物件的預設超時時間(浮點數,單位秒)。值為 None 表示新套接字物件沒有超時。當首次匯入套接字模組時,預設值為 None

socket.setdefaulttimeout(timeout)

設定新套接字物件的預設超時時間(浮點數,單位秒)。當套接字模組首次匯入時,預設值為 None。有關可能的值及其各自含義,請參閱 settimeout()

socket.sethostname(name)

將機器的主機名設定為 *name*。如果您沒有足夠的許可權,這將引發 OSError

使用引數 name 觸發 審計事件 socket.sethostname

可用性:Unix,非 Android。

在 3.3 版本加入。

socket.if_nameindex()

返回網路介面資訊 (索引整數,名稱字串) 元組列表。OSError 如果系統呼叫失敗。

可用性:Unix, Windows, 非 WASI。

在 3.3 版本加入。

3.8 版更改: 添加了 Windows 支援。

備註

在 Windows 上,網路介面在不同的上下文中具有不同的名稱(所有名稱均為示例)

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

  • 名稱: ethernet_32770

  • 友好名稱: vEthernet (nat)

  • 描述: Hyper-V Virtual Ethernet Adapter

此函式返回列表中第二種形式的名稱,在此示例中為 ethernet_32770

socket.if_nametoindex(if_name)

返回與介面名稱對應的網路介面索引號。如果不存在具有給定名稱的介面,則引發 OSError

可用性:Unix, Windows, 非 WASI。

在 3.3 版本加入。

3.8 版更改: 添加了 Windows 支援。

參見

“介面名稱”是 if_nameindex() 中記錄的名稱。

socket.if_indextoname(if_index)

返回與介面索引號對應的網路介面名稱。如果不存在具有給定索引的介面,則引發 OSError

可用性:Unix, Windows, 非 WASI。

在 3.3 版本加入。

3.8 版更改: 添加了 Windows 支援。

參見

“介面名稱”是 if_nameindex() 中記錄的名稱。

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

透過 AF_UNIX 套接字 *sock* 傳送檔案描述符列表 *fds*。*fds* 引數是一個檔案描述符序列。有關這些引數的文件,請參閱 sendmsg()

可用性: Unix,不包括 WASI。

支援 sendmsg()SCM_RIGHTS 機制的 Unix 平臺。

在 3.9 版本中新增。

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

AF_UNIX 套接字 *sock* 接收最多 *maxfds* 個檔案描述符。返回 (msg, list(fds), flags, addr)。有關這些引數的文件,請參閱 recvmsg()

可用性: Unix,不包括 WASI。

支援 recvmsg()SCM_RIGHTS 機制的 Unix 平臺。

在 3.9 版本中新增。

備註

檔案描述符列表末尾的任何截斷整數。

套接字物件

套接字物件具有以下方法。除了 makefile(),這些都對應於適用於套接字的 Unix 系統呼叫。

3.2 版更改: 增加了對上下文管理器協議的支援。退出上下文管理器等同於呼叫 close()

socket.accept()

接受連線。套接字必須繫結到地址並偵聽連線。返回值是一對 (conn, address),其中 *conn* 是一個 *新的* 套接字物件,可用於在連線上傳送和接收資料,*address* 是繫結到連線另一端的套接字地址。

新建立的套接字是不可繼承的

3.4 版更改: 套接字現在是不可繼承的。

3.5 版更改: 如果系統呼叫被中斷並且訊號處理程式沒有引發異常,該方法現在會重試系統呼叫,而不是引發 InterruptedError 異常(有關原因請參閱 PEP 475)。

socket.bind(address)

將套接字繫結到 *address*。套接字不得已繫結。(*address* 的格式取決於地址族 —— 請參見上文。)

使用引數 selfaddress 觸發 審計事件 socket.bind

可用性:非 WASI。

socket.close()

將套接字標記為已關閉。當所有來自 makefile() 的檔案物件都關閉時,底層系統資源(例如檔案描述符)也會關閉。一旦發生這種情況,所有對套接字物件的未來操作都將失敗。遠端端將不再接收資料(在排隊資料重新整理之後)。

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

3.6 版更改: 當底層 close() 呼叫發生錯誤時,現在會引發 OSError

備註

close() 釋放與連線關聯的資源,但不一定會立即關閉連線。如果您想及時關閉連線,請在 close() 之前呼叫 shutdown()

socket.connect(address)

連線到 *address* 處的遠端套接字。(*address* 的格式取決於地址族 —— 請參見上文。)

如果連線被訊號中斷,該方法將等待直到連線完成,或者在超時時引發 TimeoutError(如果訊號處理程式沒有引發異常且套接字是阻塞的或有超時)。對於非阻塞套接字,如果連線被訊號中斷(或訊號處理程式引發的異常),該方法將引發 InterruptedError 異常。

使用引數 selfaddress 觸發 審計事件 socket.connect

3.5 版更改: 如果連線被訊號中斷,訊號處理程式不引發異常且套接字是阻塞的或有超時,該方法現在會等待連線完成,而不是引發 InterruptedError 異常(有關原因請參閱 PEP 475)。

可用性:非 WASI。

socket.connect_ex(address)

類似於 connect(address),但對於 C 級 connect() 呼叫返回的錯誤,返回錯誤指示器而不是引發異常(其他問題,例如“找不到主機”,仍可能引發異常)。如果操作成功,錯誤指示器為 0,否則為 errno 變數的值。這對於支援非同步連線等情況很有用。

使用引數 selfaddress 觸發 審計事件 socket.connect

可用性:非 WASI。

socket.detach()

將套接字物件置於關閉狀態,而不實際關閉底層檔案描述符。檔案描述符被返回,可用於其他目的。

在 3.2 版本加入。

socket.dup()

複製套接字。

新建立的套接字是不可繼承的

3.4 版更改: 套接字現在是不可繼承的。

可用性:非 WASI。

socket.fileno()

返回套接字的檔案描述符(一個小的整數),失敗時返回 -1。這在與 select.select() 結合使用時很有用。

在 Windows 下,此方法返回的小整數不能用於檔案描述符可用的地方(例如 os.fdopen())。Unix 沒有此限制。

socket.get_inheritable()

獲取套接字的檔案描述符或套接字控制代碼的 可繼承標誌:如果套接字可以在子程序中繼承,則為 True;否則為 False

在 3.4 版本加入。

socket.getpeername()

返回套接字連線到的遠端地址。這對於查詢遠端 IPv4/v6 套接字的埠號非常有用。(返回地址的格式取決於地址族 — 參見上文。)在某些系統上不支援此函式。

socket.getpeername()

返回套接字本身的地址。這對於查詢 IPv4/v6 套接字的埠號非常有用。(返回地址的格式取決於地址族 — 參見上文。)

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

返回給定套接字選項的值(參見 Unix 手冊頁 getsockopt(2))。所需的符號常量(SO_* 等。)在此模組中定義。如果 buflen 不存在,則假定為整數選項,並由函式返回其整數值。如果 buflen 存在,它指定用於接收選項的緩衝區的最大長度,並且此緩衝區作為 bytes 物件返回。呼叫者負責解碼緩衝區的內容(請參見可選的內建模組 struct,瞭解如何解碼編碼為位元組串的 C 結構)。

可用性:非 WASI。

socket.getblocking()

如果套接字處於阻塞模式,則返回 True;如果處於非阻塞模式,則返回 False

這相當於檢查 socket.gettimeout() != 0

在 3.7 版本加入。

socket.gettimeout()

返回與套接字操作關聯的超時時間(浮點數,單位為秒),如果未設定超時,則返回 None。這反映了上次呼叫 setblocking()settimeout() 的結果。

socket.ioctl(control, option)

ioctl() 方法是 WSAIoctl 系統介面的有限介面。有關更多資訊,請參閱 Win32 文件

在其他平臺上,可以使用通用的 fcntl.fcntl()fcntl.ioctl() 函式;它們接受一個套接字物件作為它們的第一個引數。

目前僅支援以下控制程式碼:SIO_RCVALLSIO_KEEPALIVE_VALSSIO_LOOPBACK_FAST_PATH

可用性: Windows

3.6 版本中的變化: 添加了 SIO_LOOPBACK_FAST_PATH

socket.listen([backlog])

使伺服器能夠接受連線。如果指定了 backlog,它必須至少為 0(如果低於 0,則設定為 0);它指定系統在拒絕新連線之前允許的未接受連線的數量。如果未指定,則選擇預設的合理值。

可用性:非 WASI。

版本 3.5 中有所改變: backlog 引數現在是可選的。

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

返回與套接字關聯的檔案物件。返回的具體型別取決於傳遞給 makefile() 的引數。這些引數的解釋方式與內建 open() 函式相同,但唯一支援的 mode 值是 'r' (預設)、'w''b',或它們的組合。

套接字必須處於阻塞模式;它可以有超時,但如果發生超時,檔案物件的內部緩衝區可能會處於不一致狀態。

關閉由 makefile() 返回的檔案物件不會關閉原始套接字,除非所有其他檔案物件都已關閉並且已對套接字物件呼叫了 socket.close()

備註

在 Windows 上,由 makefile() 建立的類檔案物件不能用於需要帶有檔案描述符的檔案物件的地方,例如 subprocess.Popen() 的流引數。

socket.recv(bufsize[, flags])

從套接字接收資料。返回值是一個表示接收資料的位元組物件。一次要接收的最大資料量由 bufsize 指定。返回一個空的位元組物件表示客戶端已斷開連線。有關可選引數 flags 的含義,請參見 Unix 手冊頁 recv(2);它預設為零。

版本 3.5 中有所改變: 如果系統呼叫被中斷且訊號處理程式未引發異常,則該方法現在會重試系統呼叫,而不是引發 InterruptedError 異常(參見 PEP 475 以瞭解其原理)。

socket.recvfrom(bufsize[, flags])

從套接字接收資料。返回值是一個對 (bytes, address),其中 bytes 是表示接收資料的位元組物件,address 是傳送資料的套接字的地址。有關可選引數 flags 的含義,請參見 Unix 手冊頁 recv(2);它預設為零。(address 的格式取決於地址族 — 參見上文。)

版本 3.5 中有所改變: 如果系統呼叫被中斷且訊號處理程式未引發異常,則該方法現在會重試系統呼叫,而不是引發 InterruptedError 異常(參見 PEP 475 以瞭解其原理)。

版本 3.7 中有所改變: 對於多播 IPv6 地址,address 的第一個元素不再包含 %scope_id 部分。要獲取完整的 IPv6 地址,請使用 getnameinfo()

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

從套接字接收常規資料(最多 bufsize 位元組)和輔助資料。ancbufsize 引數設定用於接收輔助資料的內部緩衝區的位元組大小;它預設為 0,表示不會接收輔助資料。可以使用 CMSG_SPACE()CMSG_LEN() 計算輔助資料的適當緩衝區大小,不適合緩衝區的專案可能會被截斷或丟棄。flags 引數預設為 0,其含義與 recv() 相同。

返回值是一個 4 元組:(data, ancdata, msg_flags, address)data 項是一個 bytes 物件,包含接收到的非輔助資料。ancdata 項是一個由零個或多個元組 (cmsg_level, cmsg_type, cmsg_data) 組成的列表,表示接收到的輔助資料(控制訊息):cmsg_levelcmsg_type 是分別指定協議級別和協議特定型別的整數,cmsg_data 是一個 bytes 物件,包含關聯的資料。msg_flags 項是表示接收訊息條件的各種標誌的按位或;詳細資訊請參閱您的系統文件。如果接收套接字未連線,address 是傳送套接字的地址(如果可用);否則,其值未指定。

在某些系統上,sendmsg()recvmsg() 可用於透過 AF_UNIX 套接字在程序之間傳遞檔案描述符。當使用此功能時(通常限於 SOCK_STREAM 套接字),recvmsg() 將在其輔助資料中返回形式為 (socket.SOL_SOCKET, socket.SCM_RIGHTS, fds) 的項,其中 fds 是一個 bytes 物件,表示作為原生 C int 型別二進位制陣列的新檔案描述符。如果系統呼叫返回後 recvmsg() 引發異常,它將首先嚐試關閉透過此機制接收到的任何檔案描述符。

某些系統不指示僅部分接收的輔助資料項的截斷長度。如果某個項似乎超出了緩衝區末尾,recvmsg() 將發出 RuntimeWarning,並返回緩衝區內的部分,前提是該部分在其關聯資料開始之前未被截斷。

在支援 SCM_RIGHTS 機制的系統上,以下函式將接收最多 maxfds 個檔案描述符,返回訊息資料和包含描述符的列表(同時忽略意外情況,例如收到不相關的控制訊息)。另請參見 sendmsg()

import socket, array

def recv_fds(sock, msglen, maxfds):
    fds = array.array("i")   # Array of ints
    msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(maxfds * fds.itemsize))
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
            # Append data, ignoring any truncated integers at the end.
            fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
    return msg, list(fds)

可用性: Unix。

大多數 Unix 平臺。

在 3.3 版本加入。

版本 3.5 中有所改變: 如果系統呼叫被中斷且訊號處理程式未引發異常,則該方法現在會重試系統呼叫,而不是引發 InterruptedError 異常(參見 PEP 475 以瞭解其原理)。

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

從套接字接收常規資料和輔助資料,其行為與 recvmsg() 相同,但將非輔助資料分散到一系列緩衝區中,而不是返回新的位元組物件。buffers 引數必須是匯出可寫緩衝區(例如 bytearray 物件)的可迭代物件;這些緩衝區將填充連續的非輔助資料塊,直到所有資料都已寫入或沒有更多緩衝區。作業系統可能會限制可使用的緩衝區數量(sysconf()SC_IOV_MAX)。ancbufsizeflags 引數的含義與 recvmsg() 相同。

返回值是一個 4 元組:(nbytes, ancdata, msg_flags, address),其中 nbytes 是寫入緩衝區的非輔助資料的總位元組數,而 ancdatamsg_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---')]

可用性: Unix。

大多數 Unix 平臺。

在 3.3 版本加入。

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

從套接字接收資料,將其寫入 buffer 而不是建立新的位元組字串。返回值是一個對 (nbytes, address),其中 nbytes 是接收到的位元組數,address 是傳送資料的套接字的地址。有關可選引數 flags 的含義,請參見 Unix 手冊頁 recv(2);它預設為零。(address 的格式取決於地址族 — 參見上文。)

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

從套接字接收最多 nbytes 位元組,將資料儲存到緩衝區而不是建立新的位元組字串。如果未指定 nbytes(或為 0),則接收給定緩衝區中可用的最大大小。返回接收到的位元組數。有關可選引數 flags 的含義,請參見 Unix 手冊頁 recv(2);它預設為零。

socket.send(bytes[, flags])

向套接字傳送資料。套接字必須連線到遠端套接字。可選的 flags 引數的含義與上述 recv() 相同。返回傳送的位元組數。應用程式負責檢查所有資料是否已傳送;如果只傳輸了部分資料,應用程式需要嘗試傳送剩餘資料。有關此主題的更多資訊,請參閱 套接字程式設計指南

版本 3.5 中有所改變: 如果系統呼叫被中斷且訊號處理程式未引發異常,則該方法現在會重試系統呼叫,而不是引發 InterruptedError 異常(參見 PEP 475 以瞭解其原理)。

socket.sendall(bytes[, flags])

向套接字傳送資料。套接字必須連線到遠端套接字。可選的 flags 引數的含義與上述 recv() 相同。與 send() 不同,此方法會持續從 bytes 傳送資料,直到所有資料都被髮送或發生錯誤。None 在成功時返回。發生錯誤時,會引發異常,並且無法確定傳送了多少資料(如果有)。

版本 3.5 中有所改變: 每次資料成功傳送後,套接字超時不再重置。套接字超時現在是傳送所有資料的最大總持續時間。

版本 3.5 中有所改變: 如果系統呼叫被中斷且訊號處理程式未引發異常,則該方法現在會重試系統呼叫,而不是引發 InterruptedError 異常(參見 PEP 475 以瞭解其原理)。

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

向套接字傳送資料。套接字不應連線到遠端套接字,因為目標套接字由 address 指定。可選的 flags 引數的含義與上述 recv() 相同。返回傳送的位元組數。(address 的格式取決於地址族 — 參見上文。)

使用引數 selfaddress 觸發一個 審計事件 socket.sendto

版本 3.5 中有所改變: 如果系統呼叫被中斷且訊號處理程式未引發異常,則該方法現在會重試系統呼叫,而不是引發 InterruptedError 異常(參見 PEP 475 以瞭解其原理)。

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

向套接字傳送常規資料和輔助資料,從一系列緩衝區中收集非輔助資料並將其連線成一條訊息。buffers 引數將非輔助資料指定為類位元組物件(例如 bytes 物件)的可迭代物件;作業系統可能會限制可使用的緩衝區數量(sysconf()SC_IOV_MAX)。ancdata 引數將輔助資料(控制訊息)指定為零個或多個元組 (cmsg_level, cmsg_type, cmsg_data) 的可迭代物件,其中 cmsg_levelcmsg_type 是分別指定協議級別和協議特定型別的整數,cmsg_data 是一個類位元組物件,包含關聯資料。請注意,某些系統(特別是沒有 CMSG_SPACE() 的系統)可能僅支援每次呼叫傳送一條控制訊息。flags 引數預設為 0,其含義與 send() 相同。如果提供了 address 且不為 None,則它會為訊息設定目標地址。返回值是傳送的非輔助資料的位元組數。

在支援 SCM_RIGHTS 機制的系統上,以下函式透過 AF_UNIX 套接字傳送檔案描述符列表 fds。另請參見 recvmsg()

import socket, array

def send_fds(sock, msg, fds):
    return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, array.array("i", fds))])

可用性: Unix,不包括 WASI。

大多數 Unix 平臺。

使用引數 selfaddress 觸發一個 審計事件 socket.sendmsg

在 3.3 版本加入。

版本 3.5 中有所改變: 如果系統呼叫被中斷且訊號處理程式未引發異常,則該方法現在會重試系統呼叫,而不是引發 InterruptedError 異常(參見 PEP 475 以瞭解其原理)。

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

sendmsg() 的專用版本,用於 AF_ALG 套接字。為 AF_ALG 套接字設定模式、IV、AEAD 關聯資料長度和標誌。

可用性: Linux >= 2.6.38。

在 3.6 版本加入。

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

透過使用高效能 os.sendfile 傳送檔案直到到達 EOF,並返回傳送的總位元組數。file 必須是在二進位制模式下開啟的常規檔案物件。如果 os.sendfile 不可用(例如 Windows)或者 file 不是常規檔案,則將使用 send()offset 指示從何處開始讀取檔案。如果指定了 count,則它是要傳輸的總位元組數,而不是傳送檔案直到 EOF。檔案位置在返回時更新,或者在發生錯誤時也會更新,在這種情況下,可以使用 file.tell() 來確定已傳送的位元組數。套接字必須是 SOCK_STREAM 型別。不支援非阻塞套接字。

在 3.5 版本加入。

socket.set_inheritable(inheritable)

設定套接字的檔案描述符或套接字控制代碼的 可繼承標誌

在 3.4 版本加入。

socket.setblocking(flag)

設定套接字的阻塞或非阻塞模式:如果 flag 為 false,則套接字設定為非阻塞模式,否則設定為阻塞模式。

此方法是某些 settimeout() 呼叫的簡寫形式

  • sock.setblocking(True) 等同於 sock.settimeout(None)

  • sock.setblocking(False) 等同於 sock.settimeout(0.0)

版本 3.7 中有所改變: 該方法不再對 socket.type 應用 SOCK_NONBLOCK 標誌。

socket.settimeout(value)

在阻塞套接字操作上設定超時。value 引數可以是一個非負浮點數,表示秒數,或 None。如果給定非零值,則在操作完成之前,如果超時期限 value 已過,後續套接字操作將引發 timeout 異常。如果給定零,則套接字設定為非阻塞模式。如果給定 None,則套接字設定為阻塞模式。

欲瞭解更多資訊,請查閱 套接字超時說明

版本 3.7 中有所改變: 該方法不再切換 socket.type 上的 SOCK_NONBLOCK 標誌。

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

設定給定套接字選項的值(參見 Unix 手冊頁 setsockopt(2))。所需的符號常量在此模組中定義(SO_* 等。 <socket-unix-constants>)。該值可以是一個整數、None 或一個表示緩衝區的類位元組物件。在後一種情況下,呼叫者負責確保位元組字串包含正確的位(參見可選的內建模組 struct,瞭解如何將 C 結構編碼為位元組字串)。當 value 設定為 None 時,需要 optlen 引數。這等同於呼叫 C 函式 setsockopt(),其中 optval=NULLoptlen=optlen

3.5 版本中修改: 現在接受可寫 bytes-like object

版本 3.6 中有所改變: 添加了 setsockopt(level, optname, None, optlen: int) 形式。

可用性:非 WASI。

socket.shutdown(how)

關閉連線的一個或兩個半部。如果 howSHUT_RD,則禁止進一步接收。如果 howSHUT_WR,則禁止進一步傳送。如果 howSHUT_RDWR,則禁止進一步傳送和接收。

可用性:非 WASI。

socket.share(process_id)

複製套接字並準備好與目標程序共享。目標程序必須透過 process_id 提供。然後,生成的位元組物件可以使用某種形式的程序間通訊傳遞給目標程序,並且可以使用 fromshare() 在那裡重新建立套接字。一旦呼叫此方法,關閉套接字是安全的,因為作業系統已為目標程序複製了它。

可用性: Windows。

在 3.3 版本加入。

請注意,沒有 read()write() 方法;請改用不帶 flags 引數的 recv()send()

套接字物件還具有與傳遞給 socket 建構函式的值相對應的這些(只讀)屬性。

socket.family

套接字家族。

socket.type

套接字型別。

socket.proto

套接字協議。

套接字超時說明

套接字物件可以處於三種模式之一:阻塞、非阻塞或超時。套接字預設始終以阻塞模式建立,但可以透過呼叫 setdefaulttimeout() 來更改。

  • 阻塞模式 下,操作會阻塞直到完成或系統返回錯誤(例如連線超時)。

  • 非阻塞模式 下,如果操作無法立即完成,它們會失敗(並出現一個不幸地取決於系統的錯誤):來自 select 模組的函式可用於瞭解套接字何時以及是否可用於讀取或寫入。

  • 超時模式 下,如果操作在為套接字指定的時間內未能完成(它們會引發 timeout 異常)或系統返回錯誤,則會失敗。

備註

在作業系統層面,超時模式 下的套接字在內部設定為非阻塞模式。此外,阻塞模式和超時模式在引用同一網路端點的檔案描述符和套接字物件之間共享。如果例如您決定使用套接字的 fileno(),這種實現細節可能會產生可見的後果。

超時和 connect 方法

connect() 操作也受超時設定的約束,通常建議在呼叫 connect() 之前呼叫 settimeout(),或將超時引數傳遞給 create_connection()。但是,系統網路棧也可能會返回其自己的連線超時錯誤,而無論任何 Python 套接字超時設定如何。

超時和 accept 方法

如果 getdefaulttimeout() 不為 None,則 accept() 方法返回的套接字將繼承該超時。否則,行為取決於監聽套接字的設定:

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

  • 如果監聽套接字處於 非阻塞模式,則由 accept() 返回的套接字是阻塞模式還是非阻塞模式取決於作業系統。如果您想確保跨平臺行為,建議您手動覆蓋此設定。

示例

這裡有四個使用 TCP/IP 協議的最小示例程式:一個伺服器,它將接收到的所有資料回顯(僅服務一個客戶端),以及一個使用它的客戶端。請注意,伺服器必須執行序列 socket()bind()listen()accept()(可能會重複 accept() 以服務多個客戶端),而客戶端只需要序列 socket()connect()。另請注意,伺服器不是在監聽套接字上執行 sendall()/recv(),而是在由 accept() 返回的新套接字上執行。

前兩個示例僅支援 IPv4。

# Echo server program
import socket

HOST = ''                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()
    with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data: break
            conn.sendall(data)
# Echo client program
import socket

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b'Hello, world')
    data = s.recv(1024)
print('Received', repr(data))

接下來的兩個示例與上述兩個相同,但支援 IPv4 和 IPv6。伺服器端將監聽第一個可用的地址族(它應該同時監聽兩者)。在大多數支援 IPv6 的系統上,IPv6 將優先,伺服器可能不接受 IPv4 流量。客戶端將嘗試連線到名稱解析返回的所有地址,並向第一個成功連線的地址傳送流量。

# Echo server program
import socket
import sys

HOST = None               # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                              socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except OSError as msg:
        s = None
        continue
    try:
        s.bind(sa)
        s.listen(1)
    except OSError as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print('could not open socket')
    sys.exit(1)
conn, addr = s.accept()
with conn:
    print('Connected by', addr)
    while True:
        data = conn.recv(1024)
        if not data: break
        conn.send(data)
# Echo client program
import socket
import sys

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except OSError as msg:
        s = None
        continue
    try:
        s.connect(sa)
    except OSError as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print('could not open socket')
    sys.exit(1)
with s:
    s.sendall(b'Hello, world')
    data = s.recv(1024)
print('Received', repr(data))

下一個示例展示瞭如何在 Windows 上使用原始套接字編寫一個非常簡單的網路嗅探器。該示例需要管理員許可權才能修改介面。

import socket

# the public network interface
HOST = socket.gethostbyname(socket.gethostname())

# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))

# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# receive all packets
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

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

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

下一個示例展示瞭如何使用套接字介面透過原始套接字協議與 CAN 網路進行通訊。若要使用帶有廣播管理器協議的 CAN,請使用以下方式開啟套接字

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

繫結(CAN_RAW)或連線(CAN_BCM)套接字後,您可以像往常一樣在套接字物件上使用 socket.send()socket.recv() 操作(及其對應操作)。

這個最後一個例子可能需要特殊許可權

import socket
import struct


# CAN frame packing/unpacking (see 'struct can_frame' in <linux/can.h>)

can_frame_fmt = "=IB3x8s"
can_frame_size = struct.calcsize(can_frame_fmt)

def build_can_frame(can_id, data):
    can_dlc = len(data)
    data = data.ljust(8, b'\x00')
    return struct.pack(can_frame_fmt, can_id, can_dlc, data)

def dissect_can_frame(frame):
    can_id, can_dlc, data = struct.unpack(can_frame_fmt, frame)
    return (can_id, can_dlc, data[:can_dlc])


# create a raw socket and bind it to the 'vcan0' interface
s = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
s.bind(('vcan0',))

while True:
    cf, addr = s.recvfrom(can_frame_size)

    print('Received: can_id=%x, can_dlc=%x, data=%s' % dissect_can_frame(cf))

    try:
        s.send(cf)
    except OSError:
        print('Error sending CAN frame')

    try:
        s.send(build_can_frame(0x01, b'\x01\x02\x03'))
    except OSError:
        print('Error sending CAN frame')

在執行之間延遲過小的情況下多次執行示例,可能會導致此錯誤

OSError: [Errno 98] Address already in use

這是因為之前的執行使套接字處於 TIME_WAIT 狀態,無法立即重用。

有一個 socket 標誌可以設定,以防止這種情況,即 socket.SO_REUSEADDR

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))

SO_REUSEADDR 標誌告訴核心重用處於 TIME_WAIT 狀態的本地套接字,而無需等待其自然超時過期。

參見

有關套接字程式設計(使用 C 語言)的介紹,請參閱以下論文

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

  • An Advanced 4.3BSD Interprocess Communication Tutorial,作者 Samuel J. Leffler 等人,

兩者都包含在 UNIX Programmer's Manual, Supplementary Documents 1 (第 PS1:7 和 PS1:8 節) 中。各種套接字相關係統呼叫的平臺特定參考資料也是瞭解套接字語義細節的寶貴資訊來源。對於 Unix,請參閱手冊頁;對於 Windows,請參閱 WinSock(或 Winsock 2)規範。對於支援 IPv6 的 API,讀者可能希望參考標題為 Basic Socket Interface Extensions for IPv6 的 RFC 3493