socket
— 底層網路介面¶
原始碼: Lib/socket.py
此模組提供對 BSD 套接字介面的訪問。它在所有現代 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 上執行的程式可能需要處理這兩種型別的地址。當將其作為引數傳遞時,字串或類似位元組的物件可用於任何型別的地址。在 3.3 版本中變更: 以前,
AF_UNIX
套接字路徑假定使用 UTF-8 編碼。在 3.5 版本中變更: 現在接受可寫的 類位元組物件。
對於
AF_INET
地址族,使用一對(host, port)
,其中 *host* 是一個字串,表示 internet 域表示法(如'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)
,其中 *flowinfo* 和 *scope_id* 表示 C 中的struct sockaddr_in6
中的sin6_flowinfo
和sin6_scope_id
成員。對於socket
模組方法,為了向後相容,可以省略 *flowinfo* 和 *scope_id*。但是,請注意,省略 *scope_id* 可能會導致在操作作用域 IPv6 地址時出現問題。在 3.7 版本中變更: 對於多播地址(*scope_id* 有意義),*address* 可能不包含
%scope_id
(或zone id
)部分。此資訊是多餘的,可以安全地省略(建議)。AF_NETLINK
套接字表示為(pid, groups)
對。僅限 Linux 的對 TIPC 的支援使用
AF_TIPC
地址族。TIPC 是一種開放的、基於非 IP 的網路協議,旨在用於叢集計算機環境中。地址由一個元組表示,欄位取決於地址型別。通用元組形式為(addr_type, v1, v2, v3 [, scope])
,其中*addr_type* 是
TIPC_ADDR_NAMESEQ
、TIPC_ADDR_NAME
或TIPC_ADDR_ID
之一。*scope* 是
TIPC_ZONE_SCOPE
、TIPC_CLUSTER_SCOPE
和TIPC_NODE_SCOPE
之一。如果 *addr_type* 是
TIPC_ADDR_NAME
,則 *v1* 是伺服器型別,*v2* 是埠識別符號,*v3* 應為 0。如果 *addr_type* 是
TIPC_ADDR_NAMESEQ
,則 *v1* 是伺服器型別,*v2* 是較低的埠號,*v3* 是較高的埠號。如果 *addr_type* 是
TIPC_ADDR_ID
,則 *v1* 是節點,*v2* 是引用,*v3* 應設定為 0。
對於
AF_CAN
地址族,使用元組(interface, )
,其中 *interface* 是表示網路介面名稱(如'can0'
)的字串。網路介面名稱''
可用於接收來自此族所有網路介面的資料包。字串或元組
(id, unit)
用於PF_SYSTEM
族的SYSPROTO_CONTROL
協議。字串是使用動態分配 ID 的核心控制元件的名稱。如果知道核心控制元件的 ID 和單元號,或者使用了已註冊的 ID,則可以使用該元組。3.3 版本新增。
AF_BLUETOOTH
支援以下協議和地址格式BTPROTO_L2CAP
接受(bdaddr, psm)
,其中bdaddr
是表示為字串的藍牙地址,而psm
是整數。BTPROTO_RFCOMM
接受(bdaddr, channel)
,其中bdaddr
是表示為字串的藍牙地址,而channel
是整數。BTPROTO_HCI
接受(device_id,)
,其中device_id
是整數或包含介面藍牙地址的字串。(這取決於你的作業系統;NetBSD 和 DragonFlyBSD 需要藍牙地址,而其他所有作業系統都需要整數。)在 3.2 版本中更改: 添加了對 NetBSD 和 DragonFlyBSD 的支援。
BTPROTO_SCO
接受bdaddr
,其中bdaddr
是一個包含字串格式的藍牙地址的bytes
物件。(例如b'12:23:34:45:56:67'
)FreeBSD 不支援此協議。
AF_ALG
是一個僅限 Linux 的基於套接字的核心密碼介面。演算法套接字配置有兩到四個元素的元組(型別, 名稱 [, 特徵 [, 掩碼]])
,其中型別 是作為字串的演算法型別,例如
aead
、hash
、skcipher
或rng
。名稱 是作為字串的演算法名稱和操作模式,例如
sha256
、hmac(sha256)
、cbc(aes)
或drbg_nopr_ctr_aes256
。特徵 和 掩碼 是無符號 32 位整數。
可用性:Linux >= 2.6.38。
某些演算法型別需要較新的核心。
3.6 版本新增。
AF_VSOCK
允許虛擬機器及其主機之間進行通訊。套接字表示為(CID, 埠)
元組,其中上下文 ID 或 CID 和埠都是整數。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 - 可選的類似位元組的物件,指定硬體物理地址,其解釋取決於裝置。
可用性:Linux >= 2.2。
AF_QIPCRTR
是一個僅限 Linux 的基於套接字的介面,用於與高通平臺上的協處理器上執行的服務進行通訊。地址族表示為(節點, 埠)
元組,其中 節點 和 埠 是非負整數。可用性: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)
中。這樣的套接字應該使用 IPv4 的
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE)
或 IPv6 的socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE)
構建。可用性:Linux >= 2.6.20,FreeBSD >= 10.1
3.9 版本新增。
AF_HYPERV
是一個僅限 Windows 的基於套接字的介面,用於與 Hyper-V 主機和來賓通訊。地址族表示為(vm_id, service_id)
元組,其中vm_id
和service_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.herror¶
OSError
的一個子類,當出現與地址相關的錯誤時會引發此異常,即在 POSIX C API 中使用 h_errno 的函式,包括gethostbyname_ex()
和gethostbyaddr()
。 附帶的值是一個(h_errno, string)
對,表示庫呼叫返回的錯誤。 *h_errno* 是一個數值,而 *string* 表示 *h_errno* 的描述,由 C 函式hstrerror()
返回。在 3.3 版本中更改: 此類被設為
OSError
的子類。
- exception socket.gaierror¶
OSError
的一個子類,當getaddrinfo()
和getnameinfo()
出現與地址相關的錯誤時會引發此異常。 附帶的值是一個(error, string)
對,表示庫呼叫返回的錯誤。 *string* 表示 *error* 的描述,由 C 函式gai_strerror()
返回。 數值 *error* 值將與在此模組中定義的EAI_*
常量之一匹配。在 3.3 版本中更改: 此類被設為
OSError
的子類。
- exception socket.timeout¶
TimeoutError
的已棄用別名。OSError
的一個子類,當透過先前呼叫settimeout()
(或隱式地透過setdefaulttimeout()
) 啟用超時的套接字發生超時時,會引發此異常。 附帶的值是一個字串,其值當前始終為“timed out”。在 3.3 版本中更改: 此類被設為
OSError
的子類。在 3.10 版本中更改: 此類被設為
TimeoutError
的別名。
常量¶
AF_* 和 SOCK_* 常量現在是
AddressFamily
和SocketKind
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_STREAM
和SOCK_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_DOMAIN
,SO_PROTOCOL
,SO_PEERSEC
,SO_PASSSEC
,TCP_USER_TIMEOUT
,TCP_CONGESTION
。在 3.6.5 版本中更改: 在 Windows 上,如果執行時 Windows 支援,則會出現
TCP_FASTOPEN
,TCP_KEEPCNT
。在 3.7 版本中更改: 添加了
TCP_NOTSENT_LOWAT
。在 Windows 上,如果執行時 Windows 支援,則會出現
TCP_KEEPIDLE
,TCP_KEEPINTVL
。在 3.10 版本中更改: 添加了
IP_RECVTOS
。添加了TCP_KEEPALIVE
。在 MacOS 上,此常量的使用方式與 Linux 上TCP_KEEPIDLE
的使用方式相同。在 3.11 版本中更改: 添加了
TCP_CONNECTION_INFO
。在 MacOS 上,此常量的使用方式與 Linux 和 BSD 上TCP_INFO
的使用方式相同。在 3.12 版本中更改: 添加了
SO_RTABLE
和SO_USER_COOKIE
。在 OpenBSD 和 FreeBSD 上,這些常量可以分別以與 Linux 上SO_MARK
相同的方式使用。還添加了 Linux 中缺少的 TCP 套接字選項:TCP_MD5SIG
、TCP_THIN_LINEAR_TIMEOUTS
、TCP_THIN_DUPACK
、TCP_REPAIR
、TCP_REPAIR_QUEUE
、TCP_QUEUE_SEQ
、TCP_REPAIR_OPTIONS
、TCP_TIMESTAMP
、TCP_CC_INFO
、TCP_SAVE_SYN
、TCP_SAVED_SYN
、TCP_REPAIR_WINDOW
、TCP_FASTOPEN_CONNECT
、TCP_ULP
、TCP_MD5SIG_EXT
、TCP_FASTOPEN_KEY
、TCP_FASTOPEN_NO_COOKIE
、TCP_ZEROCOPY_RECEIVE
、TCP_INQ
、TCP_TX_DELAY
。添加了IP_PKTINFO
、IP_UNBLOCK_SOURCE
、IP_BLOCK_SOURCE
、IP_ADD_SOURCE_MEMBERSHIP
、IP_DROP_SOURCE_MEMBERSHIP
。在 3.13 版本中更改: 添加了
SO_BINDTOIFINDEX
。在 Linux 上,此常量可以與SO_BINDTODEVICE
以相同的方式使用,但使用的是網路介面的索引,而不是其名稱。
- socket.AF_CAN¶
- socket.PF_CAN¶
- SOL_CAN_*
- CAN_*
Linux 文件中記錄的許多此類形式的常量,也在 socket 模組中定義。
可用性: Linux >= 2.6.25, NetBSD >= 8。
3.3 版本新增。
在 3.11 版本中更改: 添加了 NetBSD 支援。
- socket.CAN_BCM¶
- CAN_BCM_*
CAN 協議族中的 CAN_BCM 是廣播管理器(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 協議族中的 CAN_ISOTP 是 ISO-TP (ISO 15765-2) 協議。Linux 文件中記錄的 ISO-TP 常量。
可用性: Linux >= 2.6.25。
3.7 版本新增。
- socket.CAN_J1939¶
CAN 協議族中的 CAN_J1939 是 SAE J1939 協議。Linux 文件中記錄的 J1939 常量。
可用性: 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_VSOCK¶
- socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID¶
- VMADDR*
- SO_VM*
用於 Linux 主機/客機通訊的常量。
可用性: Linux >= 4.8。
3.7 版本新增。
- socket.has_ipv6¶
此常量包含一個布林值,指示此平臺上是否支援 IPv6。
- socket.BDADDR_ANY¶
- socket.BDADDR_LOCAL¶
這些是包含具有特殊含義的藍牙地址的字串常量。 例如,
BDADDR_ANY
可用於在使用BTPROTO_RFCOMM
指定繫結套接字時指示任何地址。
- 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。
- 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.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_INET6
、AF_UNIX
、AF_CAN
、AF_PACKET
或AF_RDS
。套接字型別應該是SOCK_STREAM
(預設值)、SOCK_DGRAM
、SOCK_RAW
或者其他SOCK_
常量之一。協議號通常為零,可以省略;如果地址族為AF_CAN
,則協議應為CAN_RAW
、CAN_BCM
、CAN_ISOTP
或CAN_J1939
之一。如果指定了 fileno,則 family、type 和 proto 的值將從指定的檔案描述符自動檢測。可以透過使用顯式的 family、type 或 proto 引數呼叫函式來覆蓋自動檢測。這隻會影響 Python 如何表示,例如
socket.getpeername()
的返回值,而不會影響實際的作業系統資源。與socket.fromfd()
不同,fileno 將返回相同的套接字,而不是重複的套接字。這有助於使用socket.close()
關閉分離的套接字。新建立的套接字是 不可繼承的。
引發一個 審計事件
socket.__new__
,引數為self
、family
、type
、protocol
。在 3.3 版本中更改: 添加了 AF_CAN 系列。添加了 AF_RDS 系列。
在 3.4 版本中更改: 添加了 CAN_BCM 協議。
在 3.4 版本中更改: 現在返回的套接字是不可繼承的。
在 3.7 版本中更改: 添加了 CAN_ISOTP 協議。
在 3.7 版本中更改: 當將
SOCK_NONBLOCK
或SOCK_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_INET
。新建立的套接字是 不可繼承的。
在 3.2 版本中更改: 現在返回的套接字物件支援整個套接字 API,而不僅僅是子集。
在 3.4 版本中更改: 現在返回的套接字是不可繼承的。
在 3.5 版本中更改: 添加了 Windows 支援。
- socket.create_connection(address, timeout=GLOBAL_DEFAULT, source_address=None, *, all_errors=False)¶
連線到在 internet address(一個 2 元組
(host, port)
)上偵聽的 TCP 服務,並返回套接字物件。這是一個比socket.connect()
更高級別的函式:如果 host 是一個非數字主機名,它將嘗試為AF_INET
和AF_INET6
解析它,然後依次嘗試連線到所有可能的地址,直到連線成功。這使得編寫與 IPv4 和 IPv6 相容的客戶端變得容易。傳遞可選的 timeout 引數將在嘗試連線之前在套接字例項上設定超時。如果沒有提供 timeout,則使用
getdefaulttimeout()
返回的全域性預設超時設定。如果提供,source_address 必須是一個 2 元組
(host, port)
,以便套接字在連線之前繫結到它作為源地址。如果 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_INET
或AF_INET6
。backlog 是傳遞給socket.listen()
的佇列大小;如果未指定,則選擇預設的合理值。reuse_port 指示是否設定SO_REUSEPORT
套接字選項。如果 dualstack_ipv6 為 true 並且平臺支援它,則該套接字將能夠接受 IPv4 和 IPv6 連線,否則將引發
ValueError
。大多數 POSIX 平臺和 Windows 都應該支援此功能。啟用此功能後,當發生 IPv4 連線時,socket.getpeername()
返回的地址將是表示為 IPv4 對映的 IPv6 地址的 IPv6 地址。如果 dualstack_ipv6 為 false,它將在預設啟用此功能的平臺(例如 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.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
。透過將None
作為 host 和 port 的值傳遞,可以將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_STREAM
或SOCK_DGRAM
)和/或 proto (例如,IPPROTO_TCP
或IPPROTO_UDP
)來限制結果,您的應用程式可以處理。family、type、proto 和 flags 的預設值的行為是特定於系統的。
許多系統(例如,大多數 Linux 配置)將返回所有匹配地址的排序列表。這些地址通常應該按順序嘗試,直到連線成功(可能並行嘗試,例如,使用 Happy Eyeballs 演算法)。在這些情況下,限制 type 和/或 proto 可以幫助消除不成功或不可用的連線嘗試。
但是,某些系統只會返回單個地址。(例如,這在 Solaris 和 AIX 配置上報告過。)在這些系統上,限制 type 和/或 proto 有助於確保此地址可用。
使用引數
host
、port
、family
、type
、protocol
引發 審計事件socket.getaddrinfo
。以下示例為埠 80 上的
example.org
的假設 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 名稱解析,應使用getaddrinfo()
來支援 IPv4/v6 雙棧。引發帶有引數
hostname
的 審計事件socket.gethostbyname
。可用性: 不適用於 WASI。
- socket.gethostbyname_ex(hostname)¶
將主機名轉換為 IPv4 地址格式,擴充套件介面。返回一個 3 元組
(hostname, aliaslist, ipaddrlist)
,其中 hostname 是主機的主要主機名,aliaslist 是同一地址的備用主機名(可能為空)列表,而 ipaddrlist 是同一主機上同一介面的 IPv4 地址列表(通常但不總是單個地址)。gethostbyname_ex()
不支援 IPv6 名稱解析,應使用getaddrinfo()
來支援 IPv4/v6 雙棧。引發帶有引數
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)¶
將點分十進位制字串格式(例如,‘123.45.67.89’)的 IPv4 地址轉換為 32 位打包二進位制格式,以長度為四個字元的位元組物件表示。當與使用標準 C 庫且需要
in_addr
型別物件(即此函式返回的 32 位打包二進位制的 C 型別)的程式互動時,此操作非常有用。inet_aton()
也接受少於三個點的字串;詳情請參閱 Unix 手冊頁 inet(3)。如果傳遞給此函式的 IPv4 地址字串無效,則會引發
OSError
。請注意,具體什麼被認為是有效取決於底層 C 實現的inet_aton()
。inet_aton()
不支援 IPv6,應使用inet_pton()
來支援 IPv4/v6 雙棧。
- socket.inet_ntoa(packed_ip)¶
將 32 位打包的 IPv4 地址(長度為四個位元組的 類位元組物件)轉換為其標準的點分十進位制字串表示形式(例如,‘123.45.67.89’)。當與使用標準 C 庫且需要
in_addr
型別物件(即此函式接收的 32 位打包二進位制資料的 C 型別)的程式互動時,此操作非常有用。如果傳遞給此函式的位元組序列的長度不是正好 4 個位元組,則會引發
OSError
。inet_ntoa()
不支援 IPv6,應使用inet_ntop()
來支援 IPv4/v6 雙棧。在 3.5 版本中變更: 現在接受可寫的 類位元組物件。
- socket.inet_pton(address_family, ip_string)¶
將 IP 地址從其特定於地址族的字串格式轉換為打包的二進位制格式。
inet_pton()
在庫或網路協議需要in_addr
型別物件(類似於inet_aton()
)或in6_addr
時很有用。目前支援的 *address_family* 值是
AF_INET
和AF_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_INET
和AF_INET6
。如果位元組物件 *packed_ip* 對於指定的地址族而言長度不正確,則會引發ValueError
。對於呼叫inet_ntop()
產生的錯誤,會引發OSError
。可用性:Unix,Windows。
在 3.4 版本中更改: 添加了 Windows 支援
在 3.5 版本中變更: 現在接受可寫的 類位元組物件。
- 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
值表示新套接字物件沒有超時。首次匯入 socket 模組時,預設值為None
。
- socket.setdefaulttimeout(timeout)¶
設定新套接字物件的預設超時時間,單位為秒(浮點數)。當首次匯入套接字模組時,預設值為
None
。有關可能的值及其各自的含義,請參閱settimeout()
。
- socket.sethostname(name)¶
將機器的主機名設定為name。 如果您沒有足夠的許可權,這將引發
OSError
。引發一個 審計事件
socket.sethostname
,引數為name
。可用性: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()
中記錄的名稱。
套接字物件¶
套接字物件具有以下方法。除了 makefile()
之外,這些方法對應於適用於套接字的 Unix 系統呼叫。
- socket.accept()¶
接受連線。套接字必須繫結到地址並偵聽連線。返回值是一對
(conn, address)
,其中 conn 是一個新的套接字物件,可用於在連線上傳送和接收資料,而 address 是繫結到連線另一端套接字的地址。新建立的套接字是 不可繼承的。
在 3.4 版本中變更: 套接字現在是不可繼承的。
在 3.5 版本中變更: 如果系統呼叫被中斷,並且訊號處理程式沒有引發異常,則該方法現在會重試系統呼叫,而不是引發
InterruptedError
異常(有關基本原理,請參閱 PEP 475)。
- socket.bind(address)¶
將套接字繫結到 address。該套接字不能已經繫結。(address 的格式取決於地址族 — 請參見上文。)
引發一個 審計事件
socket.bind
,引數為self
、address
。可用性: 不適用於 WASI。
- socket.close()¶
標記套接字已關閉。當來自
makefile()
的所有檔案物件都關閉時,也會關閉底層系統資源(例如,檔案描述符)。一旦發生這種情況,對套接字物件的所有未來操作都將失敗。遠端端將不會接收到更多資料(在重新整理排隊資料之後)。套接字在被垃圾回收時會自動關閉,但建議顯式
close()
它們,或者在它們周圍使用with
語句。在 3.6 版本中變更: 如果在呼叫底層
close()
時發生錯誤,則現在會引發OSError
。註解
close()
釋放與連線關聯的資源,但不一定會立即關閉連線。 如果您想及時關閉連線,請在呼叫close()
之前呼叫shutdown()
。
- socket.connect(address)¶
連線到 address 指定的遠端套接字。(address 的格式取決於地址族——請參見上文。)
如果連線被訊號中斷,該方法會等待連線完成,或者在超時時引發
TimeoutError
異常,前提是訊號處理程式沒有引發異常並且套接字是阻塞的或具有超時。對於非阻塞套接字,如果連線被訊號中斷(或訊號處理程式引發異常),則該方法會引發InterruptedError
異常。引發一個 審計事件
socket.connect
,其引數為self
和address
。在 3.5 版本中更改: 如果連線被訊號中斷,訊號處理程式沒有引發異常並且套接字是阻塞的或具有超時(參見 PEP 475 獲取理由),該方法現在會等待連線完成,而不是引發
InterruptedError
異常。可用性: 不適用於 WASI。
- socket.connect_ex(address)¶
類似於
connect(address)
,但對於 C 級別的connect()
呼叫返回的錯誤,它會返回一個錯誤指示符,而不是引發異常(其他問題,例如“找不到主機”,仍然會引發異常)。如果操作成功,錯誤指示符為0
,否則為errno
變數的值。這對於支援例如非同步連線非常有用。引發一個 審計事件
socket.connect
,其引數為self
和address
。可用性: 不適用於 WASI。
- socket.detach()¶
將套接字物件置於關閉狀態,而不實際關閉底層檔案描述符。返回檔案描述符,可將其重新用於其他目的。
在 3.2 版本中新增。
- socket.fileno()¶
返回套接字的檔案描述符(一個小的整數),如果失敗則返回 -1。 這對於
select.select()
非常有用。在 Windows 下,此方法返回的小整數不能用於可以使用檔案描述符的地方(例如
os.fdopen()
)。 Unix 沒有此限制。
- socket.get_inheritable()¶
獲取套接字的檔案描述符或套接字控制代碼的可繼承標誌:如果套接字可以在子程序中繼承,則為
True
,如果不能,則為False
。在 3.4 版本中新增。
- socket.getpeername()¶
返回套接字連線到的遠端地址。 例如,這對於找出遠端 IPv4/v6 套接字的埠號非常有用。(返回的地址格式取決於地址族——請參見上文。)在某些系統上,不支援此功能。
- socket.getsockname()¶
返回套接字自己的地址。 例如,這對於找出 IPv4/v6 套接字的埠號非常有用。(返回的地址格式取決於地址族——請參見上文。)
- socket.getsockopt(level, optname[, buflen])¶
返回給定套接字選項的值(請參見 Unix 手冊頁 getsockopt(2))。 此模組中定義了所需的符號常量(SO_* 等)。 如果缺少 buflen,則假定為整數選項,並且該函式的返回值為整數值。 如果存在 buflen,則它指定用於接收選項的緩衝區的最大長度,並且此緩衝區作為位元組物件返回。 呼叫方需要解碼緩衝區的內容(有關解碼編碼為位元組字串的 C 結構的方法,請參見可選的內建模組
struct
)。可用性: 不適用於 WASI。
- socket.getblocking()¶
如果套接字處於阻塞模式,則返回
True
,如果處於非阻塞模式,則返回False
。這等效於檢查
socket.gettimeout() != 0
。3.7 版本新增。
- socket.gettimeout()¶
返回與套接字操作關聯的超時時間(以秒為單位的浮點數),如果沒有設定超時,則返回
None
。 這反映了上次對setblocking()
或settimeout()
的呼叫。
- socket.ioctl(control, option)¶
- 平臺:
Windows
ioctl()
方法是 WSAIoctl 系統介面的有限介面。 請參閱 Win32 文件瞭解更多資訊。在其他平臺上,可以使用通用的
fcntl.fcntl()
和fcntl.ioctl()
函式; 它們接受套接字物件作為它們的第一個引數。目前僅支援以下控制程式碼:
SIO_RCVALL
、SIO_KEEPALIVE_VALS
和SIO_LOOPBACK_FAST_PATH
。在 3.6 版本中更改: 添加了
SIO_LOOPBACK_FAST_PATH
。
- socket.listen([backlog])¶
使伺服器能夠接受連線。 如果指定了 backlog,則它必須至少為 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);它預設為零。
註解
為了與硬體和網路實際情況最佳匹配,bufsize 的值應為相對較小的 2 的冪,例如 4096。
在 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_level 和 cmsg_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
) 可用的緩衝區數量。ancbufsize 和 flags 引數的含義與recvmsg()
相同。返回值是一個 4 元組:
(nbytes, ancdata, msg_flags, address)
,其中 nbytes 是寫入緩衝區的非輔助資料的總位元組數,而 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---')]
可用性: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()
相同。返回傳送的位元組數。應用程式負責檢查是否已傳送所有資料;如果僅傳輸了部分資料,則應用程式需要嘗試傳遞剩餘資料。有關此主題的更多資訊,請查閱 套接字程式設計 HOWTO。在 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 的格式取決於地址族 — 請參見上文。)引發一個 審計事件
socket.sendto
,其引數為self
和address
。在 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_level 和 cmsg_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 平臺。
引發一個帶引數
self
和address
的 審計事件socket.sendmsg
。3.3 版本新增。
在 3.5 版本中更改: 如果系統呼叫被中斷且訊號處理程式未引發異常,則該方法現在會重試系統呼叫,而不是引發
InterruptedError
異常(有關原理,請參閱 PEP 475)。
- socket.sendmsg_afalg([msg, ]*, op[, iv[, assoclen[, flags]]])¶
AF_ALG
套接字的sendmsg()
的專門版本。為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.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: buffer)
- socket.setsockopt(level, optname, None, optlen: int)
設定給定套接字選項的值(請參閱 Unix 手冊頁 setsockopt(2))。所需的符號常量在此模組中定義(SO_* 等 <socket-unix-constants>)。值可以是整數、
None
或表示緩衝區的類位元組物件。在後一種情況下,由呼叫方確保位元組串包含正確的位(有關將 C 結構編碼為位元組串的方法,請參閱可選的內建模組struct
)。當 value 設定為None
時,需要 optlen 引數。它等效於使用optval=NULL
和optlen=optlen
呼叫setsockopt()
C 函式。在 3.5 版本中變更: 現在接受可寫的 類位元組物件。
在 3.6 版本中更改: 添加了 setsockopt(level, optname, None, optlen: int) 形式。
可用性: 不適用於 WASI。
- socket.shutdown(how)¶
關閉連線的一個或兩個半邊。如果 how 是
SHUT_RD
,則禁止進一步接收。如果 how 是SHUT_WR
,則禁止進一步傳送。如果 how 是SHUT_RDWR
,則禁止進一步傳送和接收。可用性: 不適用於 WASI。
複製一個套接字,並準備將其與目標程序共享。必須向目標程序提供 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()
方法返回的套接字將繼承該超時。否則,該行為取決於偵聽套接字的設定
示例¶
以下是使用 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 語言)的介紹,請參閱以下論文
《4.3BSD 程序間通訊入門教程》,作者:Stuart Sechrest
《4.3BSD 高階程序間通訊教程》,作者:Samuel J. Leffler 等
這兩篇論文都收錄於 UNIX 程式設計師手冊,補充文件 1(PS1:7 和 PS1:8 部分)。各種與套接字相關的系統呼叫的特定於平臺的參考資料也是瞭解套接字語義細節的重要來源。對於 Unix,請參考手冊頁;對於 Windows,請參閱 WinSock(或 Winsock 2)規範。對於支援 IPv6 的 API,讀者可能需要參考 RFC 3493,標題為《IPv6 的基本套接字介面擴充套件》。