檢視原始碼 socket (核心 v10.2)
Socket 介面。
此模組提供網路 socket 的 API。提供的函式可以建立、刪除和操作 socket,以及在它們之間傳送和接收資料。
目標是盡可能「接近」作業系統層級的 socket 介面。唯一顯著的附加功能是某些函式,例如 recv/3
,具有逾時參數。
注意
非同步呼叫
某些函式具有非同步呼叫。這是透過將
Timeout
參數設定為nowait
或Handle ::
reference/0
來實現的。請參閱各函式的型別規格。此模組有兩種不同的非同步呼叫實作方式。一種是在 Unix 系列作業系統上:
select
- 基於標準 socket 介面的select(3)
/poll(3)
呼叫,另一種是在 Windows 上:completion
- 基於非同步 I/O 完成埠。差異顯示在傳回值和訊息格式中,因為它們具有略微不同的語意。
completion
和select
傳回值例如,如果像這樣呼叫
recv/3
;recv(Socket, 0, nowait)
,當沒有資料可讀取時,它會傳回以下其中之一
{completion,
CompletionInfo
}
{select,
SelectInfo
}
CompletionInfo
包含 CompletionHandle,而SelectInfo
包含 SelectHandle。兩者都是reference/0
的別名。當操作可以繼續時,一個包含CompletionHandle
的completion
訊息或一個包含SelectHandle
的select
訊息會傳送至呼叫的程序。在
select
系統上,某些函式也可能傳回
{select, {
SelectInfo
, _}
這可能會發生在類型為
stream
的 socket 上,其中串流處理可以在任何點分割資料串流。請參閱各函式型別規格的傳回型別。
completion
和select
訊息
completion
訊息的格式為
{'$socket',
Socket
, completion, {
CompletionHandle
, CompletionStatus}}
select
訊息的格式為
{'$socket',
Socket
, select,
SelectHandle
}
當收到
completion
訊息(其中包含操作的結果)時,表示該操作已完成,且CompletionStatus :: ok | {error, Reason}
。請參閱各函式文件以了解Reason
的可能值,這些值與函式本身可能傳回的{error, Reason}
值相同。當收到
select
訊息時,只表示操作現在可以繼續,方法是重試該操作(可能會傳回新的{select, _}
值)。有些操作是透過重複相同的函式呼叫來重試,而有些則有專用的函式變體用於重試。請參閱各函式的文件。在
select
系統上的操作佇列在
select
系統上,所有其他程序都會被鎖定,直到目前程序完成該操作,如同在接續呼叫中傳回表示成功或失敗的值(而非select
傳回值)。其他程序會排隊並取得select
傳回值,使其等待輪到自己。取消操作
可以使用
cancel/2
取消正在進行中(尚未完成)的操作,無論是在completion
或select
系統上。取消操作可確保在
cancel/2
呼叫之後,收件匣中沒有completion
、select
或abort
訊息。使用
Handle
如果使用
make_ref()
建立reference/0
,並將其用作Timeout | Handle
參數,則相同的Handle
將會是傳回的select_info/0
中的SelectHandle
以及收到的select
訊息,或者是傳回的completion_info/0
中的CompletionHandle
以及收到的completion
訊息。然後,編譯器可以最佳化後續的
receive
陳述式,使其僅掃描在建立reference/0
之後到達的訊息。如果訊息佇列很大,這是一項很大的最佳化。對於呼叫,
reference/0
必須是唯一的。在
select
系統上重複操作在
select
系統上,如果在收到select
訊息之前重複呼叫,則會取代正在進行中的呼叫{select, {select_info, Handle}} = socket:accept(LSock, nowait), {error, timeout} = socket:accept(LSock, 500), :
在上述情況中,一旦進行第二次
accept/2
呼叫,Handle
便不再有效(第一次呼叫會自動取消)。在第二次accept/2
呼叫傳回{error, timeout}
之後,接受操作即已完成。請注意,這裡存在競爭條件;無法知道呼叫是否在傳送
select
訊息之前重複,因為它可能在重複呼叫之前剛傳送。因此,現在收件匣中可能會有包含Handle
的select
訊息。
abort
訊息使用者必須準備好的另一個訊息(當使用
nowait | Handle
時)是abort
訊息
{'$socket',
Socket
, abort, Info}
此訊息表示正在進行中的操作已中止。例如,如果 socket 已由另一個程序關閉;
Info
將會是{Handle, closed}
。
注意
已實作對 IPv6 的支援,但尚未經過完整測試。
SCTP 僅部分實作(且未經測試)。
此模組在 OTP 22.0 中以實驗性程式碼的形式引入。
- 在 OTP 22.1 中,為許多函式新增了
nowait
參數,並新增了cancel/2
和info/1
函式。 - 在 OTP 22.3 中,新增了
number_of/0
函式。 - 在 OTP 23.0 中,新增了函式
is_supported/1,2
和具有FD
參數的open/1,2
函式。 - 在 OTP 23.1 中,新增了
use_registry/1
函式。 - 在 OTP 24.0 中,為許多函式新增了
select_handle/0
參數,並新增了cancel/1
、cancel_monitor/1
、具有元組選項的getopt/3
、getopt_native/3
、info/0
、monitor/1
、具有選項清單的open/3
、許多recv/*
、recvfrom/*
、recvmsg/*
、send/*
、sendmsg/*
、sendto/*
函式、sendfile/*
函式以及setopt/3
、setopt_native/3
函式。 - 在 OTP 24.1 中,新增了
i/*
函式。 - 在 OTP 24.2 中,新增了
ioctl/*
函式。 - 在 OTP 26.0 中,為許多函式新增了
completion_handle/0
參數,並新增了具有completion_info/0
參數的cancel/2
函式。也就是說,新增了對 Windows 非同步 I/O 完成埠的支援。以 Unix 風格為主(select 句柄)的 API 功能可以認為不再是實驗性的。 - 在 OTP 27.0 中,以 Windows 風格為主(completion 句柄)的 API 功能可以認為不再是實驗性的。
範例
client(SAddr, SPort) ->
{ok, Sock} = socket:open(inet, stream, tcp),
ok = socket:connect(Sock, #{family => inet,
addr => SAddr,
port => SPort}),
Msg = <<"hello">>,
ok = socket:send(Sock, Msg),
ok = socket:shutdown(Sock, write),
{ok, Msg} = socket:recv(Sock),
ok = socket:close(Sock).
server(Addr, Port) ->
{ok, LSock} = socket:open(inet, stream, tcp),
ok = socket:bind(LSock, #{family => inet,
port => Port,
addr => Addr}),
ok = socket:listen(LSock),
{ok, Sock} = socket:accept(LSock),
{ok, Msg} = socket:recv(Sock),
ok = socket:send(Sock, Msg),
ok = socket:close(Sock),
ok = socket:close(LSock).
摘要
型別
控制訊息(輔助訊息)。
由 recvmsg/1,2,3,5
傳回的控制訊息(輔助訊息)。
由 sendmsg/2,3,4
接受的控制訊息(輔助訊息)。
協定網域,又稱位址系列。
擴充錯誤資訊。
平台相依的資訊項目。
介面類型(資料鏈路)。我們只將少數值轉換為原子,其餘值則保留為(無號)整數值。
C:struct ip_mreq
C:struct ip_mreq_source
C:struct ip_msfilter
C:struct ip_pktinfo
C:IP_PMTUDISC_*
值。
C:IPTOS_*
值。
IPv6 躍點限制值。
C:struct ipv6_mreq
C:struct in6_pktinfo
C:IPV6_PMTUDISC_*
值
協定層級。
C:struct linger
C:struct msghdr
平台相依的訊息旗標。
由 recvmsg/1,2,3,5
傳回的訊息。
由 sendmsg/2,3,4
傳送的訊息。
協定層級 otp
socket 選項。
Posix 錯誤碼。
協定名稱。
C:struct sctp_assocparams
C: struct sctp_event_subscribe
。
C: struct sctp_initmsg
。
C: struct sctp_rtoinfo
。
選擇操作 控制代碼。
選擇操作 資訊。
選擇操作 標籤。
C: struct sockaddr_dl
C: struct sockaddr_in6
C: struct sockaddr_in
C: struct sockaddr_ll
C: struct sockaddr
C: struct sockaddr_un
。
C: AF_UNSPEC
的 struct sockaddr
根據此模組的 socket。
一個 map/0
,其包含 名稱 := 計數器
的關聯。
Socket 的不透明控制代碼,對 socket 而言是唯一的。
Socket 選項。
C: struct timeval
協定類型。
函數
在監聽 socket 上接受連線。
將名稱繫結到 socket。
取消進行中的非同步呼叫。
取消 socket 監視器。
關閉 socket。
完成 connect/3
操作。
將 socket 連接到指定的位址。
取得 socket 選項的值。
取得 socket 選項(為了向後相容的函數)。
取得「原生」socket 選項。
以表格格式將所有 socket 的資訊列印到 Erlang shell 中。
以表格格式將所有 socket 的資訊列印到 Erlang shell 中。
以表格格式將選取 socket 的資訊列印到 Erlang shell 中。
取得關於此 socket
程式庫的雜項資訊。
取得關於 socket 的雜項資訊。
設定 socket(裝置)參數。
取得或設定 socket(裝置)參數。
設定 socket(裝置)參數。
檢查是否支援 socket 功能。
檢查是否支援 socket 功能。
使 socket 監聽連線。
使 socket 監聽連線。
啟動 socket 監視器。
傳回使用中 socket 的數量。
等同於 open(FD, #{})
。
建立 socket。
建立 socket。
建立 socket。
傳回 socket 的遠端位址。
在連線的 socket 上接收資料。
在連線的 socket 上接收資料。
在連線的 socket 上接收資料。
在 socket 上接收訊息。
在 socket 上接收訊息。
在 socket 上接收訊息。
在 socket 上接收訊息。
在 socket 上接收訊息。
在 socket 上接收訊息。
在連線的 socket 上傳送資料。
在連線的 socket 上傳送資料。
在 socket 上傳送檔案。
在 socket 上傳送檔案。
在 socket 上傳送檔案。
在 socket 上傳送檔案。
在 socket 上傳送資料和控制訊息。
在 socket 上傳送資料和控制訊息。
在 socket 上傳送資料。
在 socket 上傳送資料。
在 socket 上傳送資料。
在連線的 socket 上傳送 erlang:iovec/0
資料。
在連線的 socket 上傳送資料,接續。
設定 socket 選項。
設定 socket 選項(為了向後相容的函數)。
設定「原生」socket 選項。
關閉全雙工連線的全部或一部分。
取得 socket 的位址。
檢索關於模組和平台支援哪些 socket 功能的資訊。
檢索關於模組和平台支援哪些 socket 功能的資訊。
檢索關於模組和平台支援哪些 socket 功能的資訊。
設定全域 use_registry
選項預設值。
傳回所有已知 socket 的清單。
傳回已篩選的已知 socket 清單。
類型
控制訊息(輔助訊息)。
-type cmsg_recv() :: #{level := socket, type := timestamp, data := binary(), value => timeval()} | #{level := socket, type := rights, data := binary()} | #{level := socket, type := credentials, data := binary()} | #{level := ip, type := tos, data := binary(), value => ip_tos() | integer()} | #{level := ip, type := recvtos, data := binary(), value := ip_tos() | integer()} | #{level := ip, type := ttl, data := binary(), value => integer()} | #{level := ip, type := recvttl, data := binary(), value := integer()} | #{level := ip, type := pktinfo, data := binary(), value => ip_pktinfo()} | #{level := ip, type := origdstaddr, data := binary(), value => sockaddr_recv()} | #{level := ip, type := recverr, data := binary(), value => extended_err()} | #{level := ipv6, type := hoplimit, data := binary(), value => integer()} | #{level := ipv6, type := pktinfo, data := binary(), value => ipv6_pktinfo()} | #{level := ipv6, type := recverr, data := binary(), value => extended_err()} | #{level := ipv6, type := tclass, data := binary(), value => integer()}.
由 recvmsg/1,2,3,5
傳回的控制訊息(輔助訊息)。
控制訊息具有帶有訊息資料原生(binary
)值的 data
欄位,如果此 socket 程式庫成功解碼資料,也可能具有已解碼的 value
欄位。
-type cmsg_send() :: #{level := socket, type := timestamp, data => native_value(), value => timeval()} | #{level := socket, type := rights, data := native_value()} | #{level := socket, type := credentials, data := native_value()} | #{level := ip, type := tos, data => native_value(), value => ip_tos() | integer()} | #{level := ip, type := ttl, data => native_value(), value => integer()} | #{level := ip, type := hoplimit, data => native_value(), value => integer()} | #{level := ipv6, type := tclass, data => native_value(), value => integer()}.
由 sendmsg/2,3,4
接受的控制訊息(輔助訊息)。
對於某些訊息類型,控制訊息可能具有帶有符號值的 value
欄位,或具有原生值的 data
欄位,該值必須與平台標頭檔案中定義的內容二進位檔相容。
-type completion_handle() :: reference().
完成操作句柄。
唯一識別(完成)操作的 reference/0
,包含在傳回的 completion_info/0
中。
-type completion_info() :: {completion_info, CompletionTag :: completion_tag(), CompletionHandle :: completion_handle()}.
完成操作資訊。
由需要呼叫端等待包含 CompletionHandle
和 操作結果的完成訊息的操作所傳回; CompletionStatus
。
-type completion_tag() ::
accept | connect | recv | recvfrom | recvmsg | send | sendto | sendmsg | sendfile.
完成操作標籤。
描述進行中(完成)操作(= 函數名稱)的標籤,包含在傳回的 completion_info/0
中。
-type domain() :: inet | inet6 | local | unspec.
協定網域,又稱位址系列。
一個小寫的 atom/0
,表示平台上名為 AF_*
(或 PF_*
)的協定網域。例如,inet
對應於 AF_INET
。
is_supported(ipv6)
告訴您是否支援 IPv6 協定,協定網域 inet6
。
is_supported(local)
告訴您是否支援協定網域 local
。
supports/0
使用單一呼叫回報兩個值,以及更多值。
-type ee_origin() :: none | local | icmp | icmp6.
-type eei() :: #{info := econnreset | econnaborted | netname_deleted | too_many_cmds | atom(), raw_info := term()}.
擴充錯誤資訊。
一個包含額外(錯誤)資訊的詞彙,如果 socket NIF 已設定為產生該資訊。
-type extended_err() :: #{error := posix(), origin := icmp, type := dest_unreach, code := icmp_dest_unreach() | 0..255, info := 0..4294967295, data := 0..4294967295, offender := sockaddr_recv()} | #{error := posix(), origin := icmp, type := time_exceeded | 0..255, code := 0..255, info := 0..4294967295, data := 0..4294967295, offender := sockaddr_recv()} | #{error := posix(), origin := icmp6, type := dest_unreach, code := icmpv6_dest_unreach() | 0..255, info := 0..4294967295, data := 0..4294967295, offender := sockaddr_recv()} | #{error := posix(), origin := icmp6, type := pkt_toobig | time_exceeded | 0..255, code := 0..255, info := 0..4294967295, data := 0..4294967295, offender := sockaddr_recv()} | #{error := posix(), origin := ee_origin() | 0..255, type := 0..255, code := 0..255, info := 0..4294967295, data := 0..4294967295, offender := sockaddr_recv()}.
-type hatype() :: netrom | eether | ether | ax25 | pronet | chaos | ieee802 | arcnet | appletlk | dlci | atm | metricom | ieee1394 | eui64 | infiniband | tunnel | tunnel6 | loopback | localtlk | none | void | non_neg_integer().
-type icmp_dest_unreach() ::
net_unreach | host_unreach | port_unreach | frag_needed | net_unknown | host_unknown.
-type icmpv6_dest_unreach() ::
noroute | adm_prohibited | not_neighbour | addr_unreach | port_unreach | policy_fail |
reject_route.
-type in6_addr() :: {0..65535, 0..65535, 0..65535, 0..65535, 0..65535, 0..65535, 0..65535, 0..65535}.
-type in6_flow_info() :: 0..1048575.
-type in6_scope_id() :: 0..4294967295.
-type in_addr() :: {0..255, 0..255, 0..255, 0..255}.
-type info() :: #{counters := #{atom() := non_neg_integer()}, iov_max := non_neg_integer(), use_registry := boolean(), io_backend := #{name := atom()}}.
平台相依的資訊項目。
iov_max
的值是系統標頭中的 IOV_MAX
常數的值,它是允許的最大 I/O 向量。另請參閱 sendmsg/4
,其中關於 msg_send/0
的 iov
鍵。根據 POSIX,允許的最小 IOV_MAX
值為 16
,但請查看您的平台文件以確保。
關於 use_registry
鍵,請參閱 use_registry/1
和具有相同名稱的 otp_socket_option/0
。
-type info_keys() ::
[domain | type | protocol | fd | owner | local_address | remote_address | recv | sent | state].
-type interface_type() :: other | hdh1822 | x25ddh | x25 | ether | ppp | loop | ipv4 | ipv6 | '6to4' | gif | faith | stf | bridge | cellular | non_neg_integer().
介面類型(資料鏈路)。我們只將少數值轉換為原子,其餘值則保留為(無號)整數值。
-type invalid() :: {invalid, What :: term()}.
-type ioctl_device_flag() ::
up | broadcast | debug | loopback | pointopoint | notrailers | knowsepoch | running | noarp |
promisc | allmulti | master | oactive | slave | simplex | link0 | link1 | link2 | multicast |
portsel | automedia | cantconfig | ppromisc | dynamic | monitor | staticarp | dying |
renaming | nogroup | lower_up | dormant | echo.
-type ioctl_device_map() :: #{mem_start := non_neg_integer(), mem_end := non_neg_integer(), base_addr := non_neg_integer(), irq := non_neg_integer(), dma := non_neg_integer(), port := non_neg_integer()}.
C:struct ip_mreq
對應於用於管理多播群組的 C struct ip_mreq
。
-type ip_mreq_source() :: #{multiaddr := in_addr(), interface := in_addr(), sourceaddr := in_addr()}.
C:struct ip_mreq_source
對應於用於管理多播群組的 C struct ip_mreq_source
。
-type ip_msfilter() :: #{multiaddr := in_addr(), interface := in_addr(), mode := include | exclude, slist := [in_addr()]}.
C:struct ip_msfilter
對應於用於管理多播來源篩選的 C struct ip_msfilter
(RFC 3376)。
-type ip_pktinfo() :: #{ifindex := non_neg_integer(), spec_dst := in_addr(), addr := in_addr()}.
C:struct ip_pktinfo
-type ip_pmtudisc() :: want | dont | do | probe.
C:IP_PMTUDISC_*
值。
對應於 C 函式庫常數 IP_PMTUDISC_*
的小寫 atom/0
值。某些常數可能不受平台支援。
-type ip_tos() :: lowdelay | throughput | reliability | mincost.
C:IPTOS_*
值。
對應於 C 函式庫常數 IPTOS_*
的小寫 atom/0
值。某些常數可能不受平台支援。
-type ipv6_hops() :: default | 0..255.
IPv6 躍點限制值。
值 default
僅在設定時有效,並轉換為 C 值 -1
,表示路由預設值。
-type ipv6_mreq() :: #{multiaddr := in6_addr(), interface := non_neg_integer()}.
C:struct ipv6_mreq
對應於用於管理多播群組的 C struct ipv6_mreq
。另請參閱 RFC 2553。
C:struct in6_pktinfo
-type ipv6_pmtudisc() :: want | dont | do | probe.
C:IPV6_PMTUDISC_*
值
對應於 C 函式庫常數 IPV6_PMTUDISC_*
的小寫 atom/0
值。某些常數可能不受平台支援。
-type level() :: socket | protocol().
協定層級。
小寫的 atom/0
作業系統協定層級,即:socket
或 protocol/0
名稱。
socket
是作業系統標頭檔中的 SOL_SOCKET
協定層級,選項名稱為 SO_
*。
-type linger() :: #{onoff := boolean(), linger := non_neg_integer()}.
C:struct linger
對應於 C struct linger
,用於管理 socket 選項 {socket, linger}
。
C:struct msghdr
-type msg_flag() ::
cmsg_cloexec | confirm | ctrunc | dontroute | eor | errqueue | more | oob | peek | trunc.
平台相依的訊息旗標。
轉換為/自平台上的訊息旗標常數。這些旗標是小寫的,而常數是大寫的,前綴為 MSG_
;例如,oob
轉換為 MSG_OOB
。
某些旗標僅用於傳送,某些僅用於接收,某些在接收到的控制訊息中,某些則用於其中幾個。並非所有平台都支援所有旗標。請參閱平台的說明文件、supports(msg_flags)
和 is_supported(msg_flags, MsgFlag)
。
-type msg_recv() :: #{addr => sockaddr_recv(), iov := erlang:iovec(), ctrl := [cmsg_recv() | #{level := level() | integer(), type := integer(), data := binary()}], flags := [msg_flag() | integer()]}.
由 recvmsg/1,2,3,5
傳回的訊息。
對應於 C struct msghdr
,請參閱平台文件以瞭解 recvmsg(2)
。
addr
- 可選的對等位址,用於未連線的 Socket。對應於struct msghdr
的msg_name
和msg_namelen
欄位。如果NULL
,則不存在該映射鍵。iov
- 以二進位清單表示的資料。struct msghdr
的msg_iov
和msg_iovlen
欄位。ctrl
- 可能為空的控制訊息清單 (CMSG)。對應於struct msghdr
的msg_control
和msg_controllen
欄位。flags
- 訊息旗標。對應於struct msghdr
的msg_flags
欄位。未知旗標 (如果有的話) 會以一個integer/0
傳回,該值位於包含清單的最後。
-type msg_send() :: #{addr => sockaddr(), iov := erlang:iovec(), ctrl => [cmsg_send() | #{level := level() | integer(), type := integer(), data := binary()}]}.
由 sendmsg/2,3,4
傳送的訊息。
對應於 C struct msghdr
,請參閱平台文件以瞭解 sendmsg(2)
。
addr
- 可選的對等位址,用於未連線的 Socket。對應於struct msghdr
的msg_name
和msg_namelen
欄位。如果未使用,則會將其設定為NULL
、0
。iov
- 必須以二進位清單表示的資料。struct msghdr
的msg_iov
和msg_iovlen
欄位。ctrl
- 可選的控制訊息清單 (CMSG)。對應於struct msghdr
的msg_control
和msg_controllen
欄位。如果未使用,則會將其設定為NULL
、0
。
struct msghdr
的 msg_flags
欄位設定為 0
。
-type otp_socket_option() ::
debug | iow | controlling_process | rcvbuf | rcvctrlbuf | sndctrlbuf | meta | use_registry |
fd | domain.
協定層級 otp
socket 選項。
otp
偽協定層級的 Socket 選項,即:{otp, Name}
選項。
此協定層級是 Erlang/OTP 的 Socket 實作層,因此高於所有作業系統協定層級。
debug
-boolean/0
- 啟動偵錯記錄。iow
-boolean/0
- 通知統計資料計數器的環繞。controlling_process
-pid/0
- Socket「擁有者」。只有目前控制程序可以設定此選項。rcvbuf
-BufSize :: (預設值 | integer()>0) | {N :: integer()>0, BufSize :: (預設值 | integer()>0)}
- 接收緩衝區大小。值
預設值
僅在設定時有效。N
指定在假設沒有更多資料在等待之前,在緊密迴路中執行讀取嘗試的次數。這是呼叫作業系統協定堆疊的接收 API 時,所使用的接收緩衝區配置大小 (在未要求特定大小 (大小 0) 的情況下)。當接收函式傳回時,接收緩衝區會重新配置為實際接收的大小。資料是否就地複製或縮小,取決於配置器,並且在 Erlang VM 中可以在某種程度上進行配置。
類似的 Socket 選項
{socket,rcvbuf}
是作業系統協定堆疊的相關選項,在 Unix 上對應於SOL_SOCKET,SO_RCVBUF
。rcvctrlbuf
-BufSize :: (預設值 | integer()>0)
- 呼叫作業系統協定堆疊的接收 API 時,所使用的輔助資料緩衝區配置大小。值
預設值
僅在設定時有效。sndctrlbuf
-BufSize :: (預設值 | integer()>0)
- 呼叫作業系統協定堆疊的 sendmsg API 時,所使用的輔助資料緩衝區配置大小。值
預設值
僅在設定時有效。使用者有責任設定足夠容納要傳送訊息中編碼輔助資料的緩衝區大小。
請參閱 sendmsg 以及
msg_send/0
類型的ctrl
欄位。fd
-integer/0
- 僅適用於取得。作業系統協定層級的 socket 描述符。函式open/1,2
可用於根據此模組,從現有的作業系統 socket 描述符建立 socket。use_registry
-boolean/0
- 僅適用於取得。當 socket 使用open/2
或open/4
建立時,會設定此值。
此處未描述的選項是有意不公開的文件,僅供 Erlang/OTP 內部使用。
-type packet_type() :: host | broadcast | multicast | otherhost | outgoing | loopback | user | kernel | fastroute | non_neg_integer().
-type port_number() :: 0..65535.
-type posix() :: inet:posix().
Posix 錯誤碼。
inet:posix/0
的本地別名,一組 atom/0
。
-type protocol() :: atom().
協定名稱。
代表作業系統協定名稱的小寫 atom/0
。例如,用於 socket_option/0
中的 控制訊息。
它們在作業系統標頭檔案中有以下名稱
ip
-IPPROTO_IP
又名SOL_IP
,選項名稱為IP_
*。ipv6
-IPPROTO_IPV6
又名SOL_IPV6
,選項名稱為IPV6_
*。tcp
-IPPROTO_TCP
,選項名稱為TCP_
*。udp
-IPPROTO_UDP
,選項名稱為UDP_
*。sctp
-IPPROTO_SCTP
,選項名稱為SCTP_
*。
還有許多其他可能的協定,但以上是這個 socket 程式庫實作 socket 選項和/或控制訊息的協定。
當 Erlang VM 啟動時,會透過 C
程式庫呼叫 getprotoent()
列舉作業系統已知的所有協定。請參閱作業系統 man page 中的 protocols(5)。如果平台支援,即使它們未列舉,列表中的那些協定也是有效的。
呼叫 is_supported(ipv6)
和 is_supported(sctp)
可用於找出平台是否支援 ipv6
和 sctp
協定,如同適當的標頭檔案和程式庫是否存在。
呼叫 is_supported(protocols, Protocol)
僅可用於找出平台是否知道指定 Protocol
的協定號碼。
請參閱 open/2,3,4
-type sctp_assocparams() :: #{assoc_id := integer(), asocmaxrxt := 0..65535, numbe_peer_destinations := 0..65535, peer_rwnd := 0..4294967295, local_rwnd := 0..4294967295, cookie_life := 0..4294967295}.
C:struct sctp_assocparams
-type sctp_event_subscribe() :: #{data_io := boolean(), association := boolean(), address := boolean(), send_failure := boolean(), peer_error := boolean(), shutdown := boolean(), partial_delivery := boolean(), adaptation_layer => boolean(), sender_dry => boolean()}.
C: struct sctp_event_subscribe
。
並非所有欄位都在所有平台上實作;未實作的欄位會被忽略,但已實作的欄位是強制性的。請注意,為了方便起見,C struct 欄位名稱中的 '_event' 後綴已被移除。
-type sctp_initmsg() ::
#{num_ostreams := 0..65535,
max_instreams := 0..65535,
max_attempts := 0..65535,
max_init_timeo := 0..65535}.
C: struct sctp_initmsg
。
-type sctp_rtoinfo() :: #{assoc_id := integer(), initial := 0..4294967295, max := 0..4294967295, min := 0..4294967295}.
C: struct sctp_rtoinfo
。
-type select_handle() :: reference().
選擇操作 控制代碼。
一個 reference/0
,唯一識別 (select) 操作,包含在回傳的 select_info/0
中。
-type select_info() :: {select_info, SelectTag :: select_tag(), SelectHandle :: select_handle()}.
選擇操作 資訊。
由需要呼叫者等待包含 SelectHandle
的 select 訊息 的操作回傳。
-type select_tag() :: accept | connect | recv | recvfrom | recvmsg | send | sendto | sendmsg | sendfile | {recv | recvfrom | recvmsg | send | sendto | sendmsg | sendfile, ContData :: term()}.
選擇操作 標籤。
描述 (select) 操作(= 函式名稱)的標籤,包含在回傳的 select_info/0
中。
-type sockaddr() :: sockaddr_in() | sockaddr_in6() | sockaddr_un() | sockaddr_ll() | sockaddr_dl() | sockaddr_unspec() | sockaddr_native().
-type sockaddr_dl() :: #{family := link, index := non_neg_integer(), type := interface_type(), nlen := non_neg_integer(), alen := non_neg_integer(), slen := non_neg_integer(), data := binary()}.
C: struct sockaddr_dl
BSD 上的連結層級位址 (PF_LINK)。
-type sockaddr_in6() :: #{family := inet6, port := port_number(), addr := any | loopback | in6_addr(), flowinfo := in6_flow_info(), scope_id := in6_scope_id()}.
C: struct sockaddr_in6
網域 inet6
(IPv6) 位址。
-type sockaddr_in() :: #{family := inet, port := port_number(), addr := any | broadcast | loopback | in_addr()}.
C: struct sockaddr_in
網域 inet
(IPv4) 位址。
-type sockaddr_ll() :: #{family := packet, protocol := non_neg_integer(), ifindex := integer(), pkttype := packet_type(), hatype := hatype(), addr := binary()}.
C: struct sockaddr_ll
C: struct sockaddr
在 C 中,struct sockaddr
,其 map/0
鍵 family
中具有 sa_family
的整數值,map/0
鍵 addr
中具有 sa_data
的內容。
C: struct sockaddr_un
。
Unix 網域 socket 位址,又名本機位址 (AF_LOCAL
)。
當從此模組傳回時,path
元素將始終是 binary
。當提供給此模組中的 API 函式時,它可以是 string/0
,它將根據平台上的 原生檔案名稱編碼編碼為二進制。
在將位址路徑提供給作業系統之前,將附加一個終止零字元,並且在將位址路徑提供給呼叫者之前,將會移除終止零。
如果位址的第一個位元組為零,Linux 的不可攜式抽象 socket 位址擴充功能會透過在任何方向上都不執行任何終止零處理來處理。
-type sockaddr_unspec() :: #{family := unspec, addr := binary()}.
C: AF_UNSPEC
的 struct sockaddr
在 C 中,struct sockaddr
,其中 sa_family = AF_UNSPEC
,map/0
鍵 addr
中具有 sa_data
的內容。
-type socket() :: {'$socket', socket_handle()}.
根據此模組的 socket。
由 open/1,2,3,4
和 accept/1,2
建立和傳回。
-type socket_counters() :: #{read_byte := non_neg_integer(), read_fails := non_neg_integer(), read_pkg := non_neg_integer(), read_pkg_max := non_neg_integer(), read_tries := non_neg_integer(), read_waits := non_neg_integer(), write_byte := non_neg_integer(), write_fails := non_neg_integer(), write_pkg := non_neg_integer(), write_pkg_max := non_neg_integer(), write_tries := non_neg_integer(), write_waits := non_neg_integer(), sendfile => non_neg_integer(), sendfile_byte => non_neg_integer(), sendfile_fails => non_neg_integer(), sendfile_max => non_neg_integer(), sendfile_pkg => non_neg_integer(), sendfile_pkg_max => non_neg_integer(), sendfile_tries => non_neg_integer(), sendfile_waits => non_neg_integer(), acc_success := non_neg_integer(), acc_fails := non_neg_integer(), acc_tries := non_neg_integer(), acc_waits := non_neg_integer()}.
一個 map/0
,其包含 名稱 := 計數器
的關聯。
-opaque socket_handle()
Socket 的不透明控制代碼,對 socket 而言是唯一的。
-type socket_info() :: #{domain := domain() | integer(), type := type() | integer(), protocol := protocol() | integer(), owner := pid(), ctype := normal | fromfd | {fromfd, integer()}, counters := socket_counters(), num_readers := non_neg_integer(), num_writers := non_neg_integer(), num_acceptors := non_neg_integer(), writable := boolean(), readable := boolean(), rstates := [atom()], wstates := [atom()]}.
-type socket_option() ::
{Level :: socket,
Opt ::
acceptconn | acceptfilter | bindtodevice | broadcast | bsp_state | busy_poll | debug |
domain | dontroute | error | exclusiveaddruse | keepalive | linger | mark | maxdg |
max_msg_size | oobinline | passcred | peek_off | peercred | priority | protocol |
rcvbuf | rcvbufforce | rcvlowat | rcvtimeo | reuseaddr | reuseport | rxq_ovfl | setfib |
sndbuf | sndbufforce | sndlowat | sndtimeo | timestamp | type} |
{Level :: ip,
Opt ::
add_membership | add_source_membership | block_source | dontfrag | drop_membership |
drop_source_membership | freebind | hdrincl | minttl | msfilter | mtu | mtu_discover |
multicast_all | multicast_if | multicast_loop | multicast_ttl | nodefrag | options |
pktinfo | recvdstaddr | recverr | recvif | recvopts | recvorigdstaddr | recvtos |
recvttl | retopts | router_alert | sndsrcaddr | tos | transparent | ttl | unblock_source} |
{Level :: ipv6,
Opt ::
addrform | add_membership | authhdr | auth_level | checksum | drop_membership | dstopts |
esp_trans_level | esp_network_level | faith | flowinfo | hopopts | ipcomp_level |
join_group | leave_group | mtu | mtu_discover | multicast_hops | multicast_if |
multicast_loop | portrange | pktoptions | recverr | recvhoplimit | hoplimit |
recvpktinfo | pktinfo | recvtclass | router_alert | rthdr | tclass | unicast_hops |
use_min_mtu | v6only} |
{Level :: tcp,
Opt ::
congestion | cork | info | keepcnt | keepidle | keepintvl | maxseg | md5sig | nodelay |
noopt | nopush | syncnt | user_timeout} |
{Level :: udp, Opt :: cork} |
{Level :: sctp,
Opt ::
adaption_layer | associnfo | auth_active_key | auth_asconf | auth_chunk | auth_key |
auth_delete_key | autoclose | context | default_send_params | delayed_ack_time |
disable_fragments | hmac_ident | events | explicit_eor | fragment_interleave |
get_peer_addr_info | initmsg | i_want_mapped_v4_addr | local_auth_chunks | maxseg |
maxburst | nodelay | partial_delivery_point | peer_addr_params | peer_auth_chunks |
primary_addr | reset_streams | rtoinfo | set_peer_primary_addr | status |
use_ext_recvinfo}.
Socket 選項。
格式為 {Level, Opt}
的 Socket 選項,其中作業系統協定 Level
= level/0
,而 Opt
是該協定層級上的 socket 選項。
選項的作業系統名稱(除非另有說明)是 Opt
atom,以大寫字母表示,並根據 level/0
加上前綴。
注意
IPv6
選項pktoptions
是一個特殊的(糟糕的)情況。它僅用於向後相容性。不要 使用這個選項。
注意
請參閱每個 socket 選項的作業系統文件。
如果以下選項的值類型為 boolean/0
,則會將值 false
轉換為值為 0
的 C int
,並將值 true
轉換為 !!0
(非(非 false))。
如果選項的值類型為 integer/0
,則會將其轉換為 C int
,其範圍可能受限,例如位元組:0..255
。請參閱作業系統文件。
呼叫 supports(options)
、supports(options, Level)
和 is_supported(options, {Level, Opt})
可用於找出平台支援哪些 socket 選項。
協定層級 socket
的選項:
{socket, acceptconn}
-Value = boolean()
{socket, bindtodevice}
-Value = string()
{socket, broadcast}
-Value = boolean()
{socket, debug}
-Value = integer()
{socket, domain}
-Value =
domain/0
僅適用於取得。
此 socket 的協定網域。在 FreeBSD 上無法運作。
{socket, dontroute}
-Value = boolean()
{socket, keepalive}
-Value = boolean()
{socket, linger}
-Value = abort |
linger/0
值
abort
是#{onoff => true, linger => 0}
的簡寫,而且只對設定有效。{socket, oobinline}
-Value = boolean()
{socket, passcred}
-Value = boolean()
{socket, peek_off}
-Value = integer()
{socket, priority}
-Value = integer()
{socket, protocol}
-Value =
protocol/0
僅適用於取得。
此 socket 的協定。在 Darwin 上無法運作。
{socket, rcvbuf}
-Value = integer()
{socket, rcvlowat}
-Value = integer()
{socket, rcvtimeo}
-Value =
timeval/0
此選項預設不受支援;必須使用
--enable-esock-rcvsndtimeo
設定選項明確建置 OTP,才能使用此選項。由於我們的實作使用非阻塞 socket,因此不清楚此選項是否有效,甚至是否可能導致故障。因此,我們不建議設定此選項。
請改為使用
Timeout
引數,例如recv/3
函式。{socket, reuseaddr}
-Value = boolean()
{socket, reuseport}
-Value = boolean()
{socket, sndbuf}
-Value = integer()
{socket, sndlowat}
-Value = integer()
{socket, sndtimeo}
-Value =
timeval/0
此選項預設不受支援;必須使用
--enable-esock-rcvsndtimeo
設定選項明確建置 OTP,才能使用此選項。由於我們的實作使用非阻塞 socket,因此不清楚此選項是否有效,甚至是否可能導致故障。因此,我們不建議設定此選項。
請改為使用
Timeout
引數,例如send/3
函式。{socket, timestamp}
-Value = boolean()
{socket, type}
-Value =
type/0
僅適用於取得。
此 socket 的類型。
協定層級的選項 ip
:
{ip, add_membership}
-Value =
ip_mreq/0
只對設定有效。
{ip, add_source_membership}
-Value =
ip_mreq_source/0
只對設定有效。
{ip, block_source}
-Value =
ip_mreq_source/0
只對設定有效。
{ip, drop_membership}
-Value =
ip_mreq/0
只對設定有效。
{ip, drop_source_membership}
-Value =
ip_mreq_source/0
只對設定有效。
{ip, freebind}
-Value = boolean()
{ip, hdrincl}
-Value = boolean()
{ip, minttl}
-Value = integer()
{ip, msfilter}
-Value =
null |
ip_msfilter/0
只對設定有效。
值
null
會將NULL
指標和大小0
傳遞給 C 程式庫呼叫。{ip, mtu}
-Value = integer()
僅適用於取得。
{ip, mtu_discover}
-Value =
ip_pmtudisc()
| integer()
依據平台的標頭檔的
integer/0
值。{ip, multicast_all}
-Value = boolean()
{ip, multicast_if}
-Value =
any |
in_addr/0
{ip, multicast_loop}
-Value = boolean()
{ip, multicast_ttl}
-Value = integer()
{ip, nodefrag}
-Value = boolean()
{ip, pktinfo}
-Value = boolean()
{ip, recvdstaddr}
-Value = boolean()
{ip, recverr}
-Value = boolean()
啟用擴充的可靠錯誤訊息傳遞。
警告! 啟用此選項後,錯誤訊息可能會出現在 socket 的錯誤佇列中,應該使用訊息旗標
errqueue
讀取,並使用recvmsg/1,2,3,4,5
在 訊息的ctrl
欄位中取得所有錯誤資訊,做為 控制訊息#{level := ip, type := recverr}
。一個可行的策略是先使用
Timeout =:= 0
和包含errqueue
的Flags
,以recvmsg/2,3,4
輪詢錯誤佇列 (忽略傳回值{error, timeout}
),然後再讀取實際資料,以確保清除錯誤佇列。並使用其中一個nowait |
select_handle()
接收函式讀取資料:recv/3,4
、recvfrom/3,4
或recvmsg/3,4,5
。否則,您可能會意外地導致 socket 的忙碌迴圈進出 'select'。{ip, recvif}
-Value = boolean()
{ip, recvopts}
-Value = boolean()
{ip, recvorigdstaddr}
-Value = boolean()
{ip, recvtos}
-Value = boolean()
{ip, recvttl}
-Value = boolean()
{ip, retopts}
-Value = boolean()
{ip, router_alert}
-Value = integer()
{ip, sendsrcaddr}
-Value = boolean()
{ip, tos}
-Value =
ip_tos()
| integer()
依據平台的標頭檔的
integer/0
值。{ip, transparent}
-Value = boolean()
{ip, ttl}
-Value = integer()
{ip, unblock_source}
-Value =
ip_mreq_source/0
只對設定有效。
協定層級的選項 ipv6
:
{ipv6, addrform}
-Value =
domain/0
據我們所知,唯一有效的值是
inet
,且只允許連接並繫結至 IPv4 對應的 IPv6 位址的 IPv6 socket。{ipv6, add_membership}
-Value =
ipv6_mreq/0
只對設定有效。
{ipv6, authhdr}
-Value = boolean()
{ipv6, drop_membership}
-Value =
ipv6_mreq/0
只對設定有效。
{ipv6, dstopts}
-Value = boolean()
{ipv6, flowinfo}
-Value = boolean()
{ipv6, hoplimit}
-Value = boolean()
{ipv6, hopopts}
-Value = boolean()
{ipv6, mtu}
-Value = integer()
{ipv6, mtu_discover}
-Value =
ipv6_pmtudisc()
| integer()
依據平台的標頭檔的
integer/0
值。{ipv6, multicast_hops}
-Value =
ipv6_hops/0
{ipv6, multicast_if}
-Value = integer()
{ipv6, multicast_loop}
-Value = boolean()
{ipv6, recverr}
-Value = boolean()
警告! 請參閱關於 socket 錯誤佇列的 socket 選項
{ip, recverr}
。相同的警告適用於此選項。{ipv6, recvhoplimit}
-Value = boolean()
{ipv6, recvpktinfo}
-Value = boolean()
{ipv6, recvtclass}
-Value = boolean()
{ipv6, router_alert}
-Value = integer()
{ipv6, rthdr}
-Value = boolean()
{ipv6, tclass}
-Value = boolean()
{ipv6, unicast_hops}
-Value =
ipv6_hops/0
{ipv6, v6only}
-Value = boolean()
協定層級的選項 sctp
。另請參閱 RFC 6458。
{sctp, associnfo}
-Value =
sctp_assocparams/0
{sctp, autoclose}
-Value = integer()
{sctp, disable_fragments}
-Value = boolean()
{sctp, events}
-Value =
sctp_event_subscribe/0
只對設定有效。
{sctp, initmsg}
-Value =
sctp_initmsg/0
{sctp, maxseg}
-Value = integer()
{sctp, nodelay}
-Value = boolean()
{sctp, rtoinfo}
-Value =
sctp_rtoinfo/0
協定層級的選項 tcp
:
{tcp, congestion}
-Value = string()
{tcp, cork}
-Value = boolean()
{tcp, maxseg}
-Value = integer()
{tcp, nodelay}
-Value = boolean()
協定層級的選項 udp
:
{udp, cork}
-Value = boolean()
C: struct timeval
對應到 C 語言的 struct timeval
。欄位 sec
保存秒數,而 usec
則保存微秒數。
-type type() :: stream | dgram | raw | rdm | seqpacket.
協定類型。
一個小寫的 atom/0
,代表平台上一個名為 SOCK_*
的協定類型。例如 stream
對應到 SOCK_STREAM
。
函式
-spec accept(ListenSocket) -> Result when Result :: {ok, Socket} | {select, SelectInfo} | {completion, CompletionInfo} | {error, Reason}, ListenSocket :: socket(), Socket :: socket(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: dynamic().
-spec accept(ListenSocket, Timeout :: infinity) -> {ok, Socket} | {error, Reason} when ListenSocket :: socket(), Socket :: socket(), Reason :: posix() | closed | invalid() | {create_accept_socket, posix()} | {add_socket, posix()} | {update_accept_context, posix()}; (ListenSocket, Timeout :: non_neg_integer()) -> {ok, Socket} | {error, Reason} when ListenSocket :: socket(), Socket :: socket(), Reason :: posix() | closed | invalid() | timeout | {create_accept_socket, posix()} | {add_socket, posix()} | {update_accept_context, posix()}; (ListenSocket, nowait | (Handle :: select_handle() | completion_handle())) -> {ok, Socket} | {select, SelectInfo} | {completion, CompletionInfo} | {error, Reason} when ListenSocket :: socket(), Socket :: socket(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: posix() | closed | invalid() | {create_accept_socket, posix()} | {add_accept_socket, posix()} | {update_accept_context, posix()}.
在監聽 socket 上接受連線。
ListenSocket
必須是連線導向型別(類型 stream
或 seqpacket
,參見 open/1
),並設定為監聽 (參見 listen/1
)。
如果 Timeout
參數為 infinity
;則接受監聽 socket 的第一個待處理的連入連線,或等待一個連線到達,並返回新的連線 socket。
如果 Timeout
參數是一個超時值 (non_neg_integer/0
);如果在 Timeout
毫秒後沒有連線到達,則返回 {error, timeout}
。
如果 Handle
參數為 nowait
(自 OTP 22.1 起),如果操作無法立即完成,則啟動一個非同步呼叫。
如果 Handle
參數是一個 select_handle/0
,(自 OTP 24.0 起),或在 Windows 上,等效的 completion_handle/0
(自 OTP 26.0 起),則像 nowait
一樣啟動一個非同步呼叫。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
-spec bind(Socket, Addr) -> ok | {error, Reason} when Socket :: socket(), Addr :: sockaddr() | any | broadcast | loopback, Reason :: posix() | closed | invalid().
將名稱繫結到 socket。
當建立 socket 時(使用 open
),它沒有被分配任何位址。bind
會分配 Addr
參數指定的位址。
用於名稱綁定的規則在不同的網域之間有所不同。
如果將 socket 綁定到例如 inet
或 inet6
位址系列的位址,並使用臨時連接埠號碼 (0
),並且想知道選擇了哪個連接埠,可以使用以下方式找到:{ok, #{port := Port}} =
socket:sockname(Socket)
-spec cancel(Socket, SelectInfo | CompletionInfo) -> ok | {error, Reason} when Socket :: socket(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: closed | invalid().
取消進行中的非同步呼叫。
呼叫此函式以取消正在進行的非同步呼叫,也就是說;它返回的值包含一個 completion_info/0
或 select_info/0
。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
如果另一個程序嘗試相同基本類型的操作 (accept/1
| send/2
| recv/2
),它將被排隊,並在當前操作以及之前排隊的所有操作完成時,透過 select
或 completion
訊息通知。如果當前操作被此函式取消,則視為已完成的操作;隊列中的第一個程序將被通知。
如果 SelectInfo
|
CompletionInfo
與呼叫程序的正在進行的操作不符,則此函式返回 {error, {invalid, SelectInfo | CompletionInfo}}
。
取消 socket 監視器。
如果 MRef
是呼叫程序透過呼叫 monitor/1
取得的參考,則此監控器會被移除。如果呼叫程序沒有此類監控器(或 MRef 與監控器不符),則不會發生任何事情。
傳回值是以下其中之一
true
- 已找到並移除監控器。在這種情況下,沒有傳遞並且將不會傳遞與此監控器對應的'DOWN'
訊息。false
- 未找到監控器,因此無法移除。這可能是因為監控器已經觸發,並且在呼叫者的訊息佇列中存在來自此監控器的'DOWN'
訊息。
-spec close(Socket) -> ok | {error, Reason} when Socket :: socket(), Reason :: posix() | closed | timeout.
關閉 socket。
注意
請注意,對於
Protocol = tcp
(參見open/3
),儘管 TCP 保證當另一端看到資料流關閉時,我們在關閉之前傳送的所有資料都已傳遞,但是我們無法知道另一端是否收到了所有資料以及資料流是否已關閉。各種網路和作業系統問題都可能會導致這種情況發生。為了獲得這樣的保證,我們需要在連線上實作一個帶內確認協定,或者可以使用
shutdown
函式來發出不再傳送任何資料的訊號,然後等待另一端關閉 socket。然後,我們將看到我們的讀取端收到一個 socket 關閉。透過這種方式,我們使用shutdown/2
實作一個小的確認協定。另一端無法知道我們是否曾經看到 socket 關閉,但在用戶端/伺服器情境中,這通常是不相關的。
-spec connect(Socket :: socket()) -> ok | {error, Reason} when Reason :: posix() | closed | invalid().
完成 connect/3
操作。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
在 select
系統上,此函式會在接收到 select
訊息 {'$socket',
Socket
, select,
SelectHandle
}
後,完成 socket 上的連線設定,並返回連線設定是否成功。
為了向後相容性,允許再次呼叫 connect/2,3
,而不是呼叫此函式,但是由於連線位址和超時參數是白費處理的,因此會產生更多的額外負擔。
完成連線操作的呼叫(第二次呼叫)無法返回 select
返回值。
-spec connect(Socket, SockAddr, Timeout :: infinity) -> ok | {error, Reason} when Socket :: socket(), SockAddr :: sockaddr(), Reason :: posix() | closed | invalid() | already | not_bound | {add_socket, posix()} | {update_connect_context, posix()}; (Socket, SockAddr, Timeout :: non_neg_integer()) -> ok | {error, Reason} when Socket :: socket(), SockAddr :: sockaddr(), Reason :: posix() | closed | invalid() | already | not_bound | timeout | {add_socket, posix()} | {update_connect_context, posix()}; (Socket, SockAddr, nowait | Handle) -> ok | {select, SelectInfo} | {completion, CompletionInfo} | {error, Reason} when Socket :: socket(), SockAddr :: sockaddr(), Handle :: select_handle() | completion_handle(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: posix() | closed | invalid() | already | not_bound | {add_socket, posix()} | {update_connect_context, posix()}.
將 socket 連接到指定的位址。
此函式將 socket 連線到 SockAddr
參數指定的位址。
如果連線嘗試已在進行中(由另一個程序),則返回 {error, already}
。
注意
在 Windows 上,socket 必須是 綁定的。
如果超時參數(參數 3)為 infinity
,則由作業系統實作決定連線嘗試何時失敗,然後決定返回什麼;可能是 {error, etimedout}
。作業系統超時時間可能非常長。
如果超時參數(參數 3)是一個超時值 (non_neg_integer/0
);如果在 Timeout
毫秒內未建立連線,則返回 {error, timeout}
。
注意
請注意,當此呼叫返回
{error, timeout}
時,socket 的連線狀態是不確定的,因為平台的網路堆疊可能會在任何時間完成連線,最多到一些平台特定的超時時間。重複嘗試連線到相同位址是可行的,但是朝向不同位址可能會導致連線到任一位址。
安全的做法是關閉 socket 並重新開始。
另請注意,這適用於取消下面描述的
nowait
連線呼叫。
如果超時參數(參數 2)為 nowait
(自 OTP 22.1 起),如果操作無法立即完成,則啟動一個非同步呼叫。
如果超時參數(參數 2)是 Handle ::
select_handle/0
,(自 OTP 24.0 起),或在 Windows 上,等效的 Handle ::
completion_handle/0
(自 OTP 26.0 起),則像 nowait
一樣啟動一個非同步呼叫。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
在接收到 select
訊息後,呼叫 connect/1
以完成操作。
-spec getopt(socket(), SocketOption :: {Level :: otp, Opt :: otp_socket_option()}) -> {ok, Value :: term()} | {error, invalid() | closed}; (socket(), SocketOption :: socket_option()) -> {ok, Value :: term()} | {error, posix() | invalid() | closed}.
取得 socket 選項的值。
從作業系統協定層級或從 otp
偽協定層級(此模組在作業系統協定層級之上的實作層級)取得作業系統協定層級 socket 選項的值。
有關 otp
協定層級的說明,請參閱類型 otp_socket_option() 。
有關此實作知道哪些作業系統協定層級選項、它們如何與作業系統選項名稱相關聯,以及它們是否有任何已知的特性,請參閱類型 socket_option/0
。
哪些選項有效取決於作業系統,以及 Socket 的類型(domain/0
、type/0
和 protocol/0
)。詳情請參閱 t:socket_option()
類型以及使用者指南中的 Socket 選項章節。
注意
並非所有選項在所有平台上都有效或可取得。也就是說,即使此
socket
實作支援某個選項,也不代表底層的作業系統也支援。
取得 socket 選項(為了向後相容的函數)。
等同於 getopt(Socket, {Level, Opt})
,或者在 Opt = {NativeOpt ::
integer/0
, ValueSpec}
的特殊情況下,等同於 getopt_native(Socket, {Level, NativeOpt}, ValueSpec)
。
請改用 getopt/2
或 getopt_native/3
來將選項層級和名稱當作單一 term 處理,並清楚區分已知選項和原生選項。
-spec getopt_native(socket(), SocketOption :: socket_option() | {Level :: level() | (NativeLevel :: integer()), NativeOpt :: integer()}, ValueType :: integer) -> {ok, Value :: integer()} | {error, posix() | invalid() | closed}; (socket(), SocketOption :: socket_option() | {Level :: level() | (NativeLevel :: integer()), NativeOpt :: integer()}, ValueType :: boolean) -> {ok, Value :: boolean()} | {error, posix() | invalid() | closed}; (socket(), SocketOption :: socket_option() | {Level :: level() | (NativeLevel :: integer()), NativeOpt :: integer()}, ValueSize :: non_neg_integer()) -> {ok, Value :: binary()} | {error, posix() | invalid() | closed}; (socket(), SocketOption :: socket_option() | {Level :: level() | (NativeLevel :: integer()), NativeOpt :: integer()}, ValueSpec :: binary()) -> {ok, Value :: binary()} | {error, posix() | invalid() | closed}.
取得「原生」socket 選項。
取得我們的實作可能不認識,或類型與我們的實作不相容的 Socket 選項;也就是說,在「原生模式」下取得。
Socket 選項可以用一般的 socket_option()
tuple 指定,其中包含已知的 Level = level()
和整數 NativeOpt
,或者同時包含整數 NativeLevel
和 NativeOpt
。
如何解碼選項值必須指定,可以使用 ValueType
指定,透過指定 ValueSize
以取得一個 binary/0
,其中將包含擷取的選項值,或者透過指定一個 binary/0
ValueSpec
,其將被複製到緩衝區中,供 getsockopt()
呼叫寫入值,該值將作為新的 binary/0
傳回。
如果 ValueType
為 integer
,則會擷取一個 C
類型 (int)
,如果為 boolean
,則會擷取一個 C
類型 (int)
,並根據 C
實作中關於 true 和 false 的概念轉換為 boolean/0
。
選項是否有效取決於平台以及 Socket 的類型(domain/0
、type/0
和 protocol/0
)。
NativeLevel
和 NativeOpt
的整數值以及 Value
編碼必須從正在執行的系統的標頭檔中推斷出來。
-spec i() -> ok.
以表格格式將所有 socket 的資訊列印到 Erlang shell 中。
每個 Socket 列印的資訊由預設的 info_keys/0
集合(所有鍵)指定。
列印的 Socket 是由此 socket
模組的實作所建立的所有 Socket。
-spec i(InfoKeys :: info_keys()) -> ok; (Domain :: inet | inet6 | local) -> ok; (Proto :: sctp | tcp | udp) -> ok; (Type :: dgram | seqpacket | stream) -> ok.
以表格格式將所有 socket 的資訊列印到 Erlang shell 中。
如果引數是 info_keys/0
的列表,則列印所有 Socket 的指定資訊。請參閱 i/0
。
-spec i(Domain :: inet | inet6 | local, InfoKeys) -> ok when InfoKeys :: info_keys(); (Proto :: sctp | tcp | udp, InfoKeys) -> ok when InfoKeys :: info_keys(); (Type :: dgram | seqpacket | stream, InfoKeys) -> ok when InfoKeys :: info_keys().
以表格格式將選取 socket 的資訊列印到 Erlang shell 中。
引數 InfoKeys
指定每個 Socket 列印哪些資訊。
如果第一個引數是 Domain
,則列印該特定 domain/0
的所有 Socket 的資訊。
如果第一個引數是 Proto
,則列印該特定 protocol/0
的所有 Socket 的資訊。
如果第一個引數是 Type
,則列印該特定 type/0
的所有 Socket 的資訊。
-spec info() -> info().
取得關於此 socket
程式庫的雜項資訊。
此函數會傳回一個 map,其中每個資訊項目都是一個鍵值對。
注意
為了確保資料完整性,會在需要時取得 mutex。因此,請勿頻繁呼叫此函數。
-spec info(Socket) -> socket_info() when Socket :: socket().
取得關於 socket 的雜項資訊。
此函數會傳回一個 map,其中每個資訊項目都是反映 Socket「目前」狀態的鍵值對。
注意
為了確保資料完整性,會在需要時取得 mutex。因此,請勿頻繁呼叫此函數。
-spec ioctl(Socket, GetRequest :: gifconf) -> {ok, IFConf :: [#{name := string, addr := sockaddr()}]} | {error, Reason} when Socket :: socket(), Reason :: posix() | closed; (Socket, GetRequest :: nread | nwrite | nspace) -> {ok, NumBytes :: non_neg_integer()} | {error, Reason} when Socket :: socket(), Reason :: posix() | closed; (Socket, GetRequest :: atmark) -> {ok, Available :: boolean()} | {error, Reason} when Socket :: socket(), Reason :: posix() | closed; (Socket, GetRequest :: tcp_info) -> {ok, Info :: map()} | {error, Reason} when Socket :: socket(), Reason :: posix() | closed.
設定 socket(裝置)參數。
此函數會根據 GetRequest
引數擷取特定參數。
gifconf
- 取得介面(傳輸層)位址的列表。結果;一個
map/0
的列表,每個介面一個,包含其名稱和位址。nread
- 取得立即可用於讀取的位元組數(自 OTP 26.1 起)。結果;位元組數,
integer/0
。nwrite
- 取得傳送佇列中的位元組數(自 OTP 26.1 起)。結果;位元組數,
integer/0
。nspace
- 取得傳送佇列中的可用空間(自 OTP 26.1 起)。結果;位元組數,
integer/0
。atmark
- 測試是否有 OOB(超出範圍)資料等待讀取(自 OTP 26.1 起)。結果;一個
boolean/0
。tcp_info
- 取得已連線 Socket 的其他 TCP 相關資訊(自 OTP 26.1 起)。結果;一個
map/0
,其中資訊項目為鍵值對。
注意
並非所有平台都支援所有請求。若要查看目前的平台是否支援 ioctl 請求
Request = nread, true = socket:is_supported(ioctl_requests, Request), :
-spec ioctl(Socket, GetRequest, NameOrIndex) -> {ok, Result} | {error, Reason} when Socket :: socket(), GetRequest :: gifname | gifindex | gifaddr | gifdstaddr | gifbrdaddr | gifnetmask | gifhwaddr | genaddr | gifmtu | giftxqlen | gifflags | tcp_info, NameOrIndex :: string() | integer(), Result :: dynamic(), Reason :: posix() | closed; (Socket, SetRequest, Value) -> ok | {error, Reason} when Socket :: socket(), SetRequest :: rcvall, Value :: off | on | iplevel, Reason :: posix() | closed; (Socket, SetRequest, Value) -> ok | {error, Reason} when Socket :: socket(), SetRequest :: rcvall_igmpmcast | rcvall_mcast, Value :: off | on, Reason :: posix() | closed.
取得或設定 socket(裝置)參數。
此函數會根據下列 GetRequest
引數之一擷取特定參數。第三個引數是(查閱)「鍵」,識別介面,對於大多數請求,介面名稱為 string/0
。此外,請參閱上面的註解。
gifname
- 取得具有指定索引的介面名稱(integer/0
)。結果;介面的名稱,
string/0
。gifindex
- 取得具有指定名稱的介面索引。結果;介面索引,
integer/0
。gifaddr
- 取得具有指定名稱的介面位址。結果;介面的位址,
sockaddr/0
。gifdstaddr
- 取得具有指定名稱的點對點介面的目的地位址。結果;介面的目的地位址,
sockaddr/0
。gifbrdaddr
- 取得具有指定名稱的介面廣播位址。結果;介面的廣播位址,
sockaddr/0
。gifnetmask
- 取得具有指定名稱的介面網路遮罩。結果;介面的網路遮罩,
sockaddr/0
。gifhwaddr
|genaddr
- 取得具有指定名稱的介面硬體位址。結果;介面的硬體位址,
sockaddr/0
|binary/0
。family 欄位包含 'ARPHRD' 裝置類型(或整數)。gifmtu
- 取得具有指定名稱的介面 MTU(最大傳輸單元)。結果;介面的 MTU,
integer/0
。giftxqlen
- 取得具有指定名稱的介面傳輸佇列長度。結果;介面的傳輸佇列長度,
integer/0
。gifflags
- 取得具有指定名稱的介面作用中旗標字組。結果;介面的作用中旗標字組,是
ioctl_device_flag/0
|
t:integer( )
的列表。
使用下列 SetRequest
引數,此函數會設定請求參數的 Value
(自 OTP 26.1 起)。
rcvall
- 啟用(或停用)Socket 以接收通過網路介面的所有 IPv4 或 IPv6 封包。Socket
必須是下列之一IPv4 Socket - 使用位址 domain
inet
、Socket typeraw
和 protocolip
建立。IPv6 Socket - 使用位址 domain
inet6
、Socket typeraw
和 protocolipv6
建立。
Socket 也必須繫結到(明確的)本機 IPv4 或 IPv6 介面(不允許
any
)。設定此 IOCTL 需要提升的權限。
使用下列 SetRequest
引數,此函數會設定請求參數的 Value
(自 OTP 26.1 起)。
rcvall_igmpmcall
- 啟用(或停用)Socket 以接收 IGMP 多點傳送 IP 流量,而不接收任何其他 IP 流量。必須使用網域
inet
、socket 類型raw
和 協定igmp
來建立 socket。此 socket 也必須綁定到一個(明確的)本機介面(不允許使用
any
)。接收緩衝區必須足夠大。
設定此 IOCTL 需要提升的權限。
rcvall_mcall
- 啟用(或停用)socket 接收所有多播 IP 流量(即,所有目的地為 224.0.0.0 到 239.255.255.255 範圍內的 IP 位址的 IP 封包)。必須使用網域
inet
、socket 類型raw
和 協定udp
來建立 socket。此 socket 也必須綁定到一個(明確的)本機介面(不允許使用
any
),並綁定到埠0
。接收緩衝區必須足夠大。
設定此 IOCTL 需要提升的權限。
-spec ioctl(Socket, SetRequest, Name, Value) -> ok | {error, Reason} when Socket :: socket(), SetRequest :: sifflags | sifaddr | sifdstaddr | sifbrdaddr | sifnetmask | sifhwaddr | sifmtu | siftxqlen, Name :: string(), Value :: dynamic(), Reason :: posix() | closed.
設定 socket(裝置)參數。
此函數根據 SetRequest
引數設定特定參數。Name
引數是介面的名稱,而 Value
引數是要設定的值。
這些操作需要提升的權限。
sifflags
- 設定具有指定名稱的介面的活動旗標字組#{Flag => boolean()}
。要變更的每個旗標都應新增至值
map/0
,如果應設定Flag
,則值為true
,如果應清除該旗標,則值為false
。sifaddr
- 設定具有指定名稱的介面的位址sockaddr/0
。sifdstaddr
- 設定具有指定名稱的點對點介面的目的地地址sockaddr/0
。sifbrdaddr
- 設定具有指定名稱的介面的廣播位址sockaddr/0
。sifnetmask
- 設定具有指定名稱的介面的網路遮罩sockaddr/0
。sifhwaddr
- 設定具有指定名稱的介面的硬體位址sockaddr/0
。sifmtu
- 設定具有指定名稱的介面的 MTU(最大傳輸單元)integer/0
。siftxqlen
- 設定具有指定名稱的介面的傳輸佇列長度integer/0
。
檢查是否支援 socket 功能。
如果 supports/0
在其傳回的列表中具有 {Key1, true}
元組或 {Key1, list()}
元組,則傳回 true
,否則傳回 false
(對於未知鍵也是如此)。
範例
true = socket:is_supported(local),
檢查是否支援 socket 功能。
如果 supports(Key1)
在其傳回的列表中具有 {Key2, true}
元組,則傳回 true
,否則傳回 false
(對於未知鍵也是如此)。
範例
true = socket:is_supported(msg_flags, errqueue),
使 socket 監聽連線。
等同於 listen(Socket, Backlog)
,其中 Backlog
使用預設值(目前為 5
)。
使 socket 監聽連線。
Backlog
引數表示未接受連入連線的佇列長度。如何解釋該數字取決於作業系統的協定堆疊,但產生的有效佇列長度很可能會被視為至少那麼長。
注意
在Windows 上,socket 必須綁定。
啟動 socket 監視器。
如果 Socket
不存在,或稍後觸發監視器,則會將 'DOWN'
訊息傳送至呼叫 monitor/1
的程序,其模式如下
{'DOWN', MonitorRef, socket, Socket, Info}
Info
是 socket 的終止原因,如果開始監視器時 Socket
不存在,則為 nosock
。
多次呼叫同一個 Socket
的 socket:monitor/1
並非錯誤;每次呼叫都會建立獨立的監視器實例。
-spec number_of() -> non_neg_integer().
傳回使用中 socket 的數量。
等同於 open(FD, #{})
。
-spec open(FD, Opts) -> {ok, Socket} | {error, Reason} when FD :: integer(), Opts :: #{domain => domain() | integer(), type => type() | integer(), protocol => default | protocol() | integer(), dup => boolean(), debug => boolean(), use_registry => boolean()}, Socket :: socket(), Reason :: posix() | domain | type | protocol; (Domain, Type) -> {ok, Socket} | {error, Reason} when Domain :: domain(), Type :: type() | integer(), Socket :: socket(), Reason :: posix() | protocol.
建立 socket。
使用引數 Domain
和 Type
等同於 open(Domain, Type, default, #{})
。
使用引數 FD
和 Opts
(自 OTP 23.0 起)
根據必須是 socket 的現有檔案描述符建立通訊端點(socket)。此函數嘗試從系統擷取檔案描述符的 domain
、type
和 protocol
。然而,這並非在所有平台上都可行;在這種情況下,應在 Opts
中指定它們。
Opts
引數可以提供額外資訊
domain
- 檔案描述符的通訊網域。另請參閱type
- 檔案描述符的 socket 類型。另請參閱
open/2,3,4
。protocol
- 檔案描述符的協定。原子default
等同於整數協定號碼0
,表示給定網域和類型的預設協定。如果無法從平台的 socket 擷取協定,且未指定
protocol
,則會使用預設協定,這可能正確也可能不正確。另請參閱
open/2,3,4
。dup
- 如果false
,則不複製提供的檔案描述符。預設為
true
;複製檔案描述符。debug
- 如果true
,則啟用 socket 除錯記錄。預設為
false
;不啟用 socket 除錯記錄。use_registry
- 啟用或停用此 socket 使用 socket 登錄。這會覆寫全域設定。預設為全域設定,請參閱
use_registry/1
。
注意
應謹慎使用此函數!
在某些平台上,必須提供
domain
、type
和protocol
,因為它們無法從平台擷取。在某些平台上,不容易取得可在這個函數中使用的檔案描述符。
-spec open(Domain, Type, Opts | Protocol) -> {ok, Socket} | {error, Reason} when Domain :: domain() | integer(), Type :: type() | integer(), Opts :: map(), Protocol :: default | protocol() | integer(), Socket :: socket(), Reason :: posix() | protocol.
建立 socket。
使用引數 Domain
、Type
和 Protocol
等同於 open(Domain, Type, Protocol, #{})
。
使用引數 Domain
、Type
和 Opts
(自 OTP 24.0 起)
-spec open(Domain, Type, Protocol, Opts) -> {ok, Socket} | {error, Reason} when Domain :: domain() | integer(), Type :: type() | integer(), Protocol :: default | protocol() | integer(), Opts :: #{netns => string(), debug => boolean(), use_registry => boolean()}, Socket :: socket(), Reason :: posix() | protocol.
建立 socket。
建立用於通訊的端點(socket)。
Domain
和 Type
可以是 integer/0
,如平台標頭檔中所定義。平台 services(5)
資料庫中定義的 Protocol
也是如此。另請參閱作業系統關於程式庫呼叫 socket(2)
的手冊頁。
注意
對於某些
Domain
和Type
的組合,平台具有可以使用Protocol = default
選擇的預設協定,而平台可能會允許或要求選擇預設協定或特定協定。範例
socket:open(inet, stream, tcp)
- 通常對於協定網域和類型inet,stream
,允許選擇tcp
協定,儘管它通常是預設協定。socket:open(local, dgram)
- 通常對於協定網域local
,必須不選擇協定,即選擇預設協定。
Opts
參數用於設定「其他」選項。以下說明支援的選項:
netns: string()
- 用於在開啟連線時設定網路命名空間。僅在 Linux 上支援。debug: boolean()
- 啟用或停用除錯記錄。預設值為
false
。use_registry: boolean()
- 啟用或停用此 socket 使用 socket 註冊表。此設定會覆蓋全域值。預設為全域值,請參閱
use_registry/1
。
-spec peername(Socket :: socket()) -> {ok, SockAddr} | {error, Reason} when SockAddr :: sockaddr_recv(), Reason :: posix() | closed.
傳回 socket 的遠端位址。
傳回已連線對等端的位址,也就是 socket 的遠端。
-spec recv(Socket :: socket(), Flags :: list()) -> dynamic(); (Socket :: socket(), Length :: non_neg_integer()) -> dynamic().
在連線的 socket 上接收資料。
使用參數 Length
;等同於 recv(Socket, Length, [], infinity)
。
使用參數 Flags
;等同於 recv(Socket, 0, Flags, infinity)
(自 OTP 24.0 起)。
-spec recv(Socket, Flags, TimeoutOrHandle) -> dynamic() when Socket :: socket(), Flags :: list(), TimeoutOrHandle :: nowait | select_handle() | completion_handle(); (Socket :: socket(), Length :: non_neg_integer(), Flags :: list()) -> dynamic(); (Socket :: socket(), Length :: non_neg_integer(), TimeoutOrHandle :: select_handle() | completion_handle()) -> dynamic().
在連線的 socket 上接收資料。
使用參數 Length
和 Flags
;等同於 recv(Socket, Length, Flags, infinity)
。
使用參數 Length
和 TimeoutOrHandle
;等同於 recv(Socket, Length, [], TimeoutOrHandle)
。TimeoutOrHandle :: nowait
自 OTP 22.1 開始允許。TimeoutOrHandle :: Handle
自 OTP 24.0 開始允許。
使用參數 Flags
和 TimeoutOrHandle
;等同於 recv(Socket, 0, Flags, TimeoutOrHandle)
(自 OTP 24.0 起)。
-spec recv(Socket, Length, Flags, Timeout :: infinity) -> {ok, Data} | {error, Reason} | {error, {Reason, Data}} when Socket :: socket(), Length :: non_neg_integer(), Flags :: [msg_flag() | integer()], Data :: binary(), Reason :: posix() | closed | invalid(); (Socket, Length, Flags, Timeout :: non_neg_integer()) -> {ok, Data} | {error, Reason} | {error, {Reason, Data}} when Socket :: socket(), Length :: non_neg_integer(), Flags :: [msg_flag() | integer()], Data :: binary(), Reason :: posix() | closed | invalid() | timeout; (Socket, Length, Flags, nowait | Handle) -> {ok, Data} | {select, SelectInfo} | {select, {SelectInfo, Data}} | {completion, CompletionInfo} | {error, Reason} | {error, {Reason, Data}} when Socket :: socket(), Length :: non_neg_integer(), Flags :: [msg_flag() | integer()], Handle :: select_handle() | completion_handle(), Data :: binary(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: posix() | closed | invalid().
在連線的 socket 上接收資料。
參數 Length
指定要接收的位元組數,特殊情況下 0
表示「所有可用」。
當 Length
為 0
時,會使用預設緩衝區大小,可以使用 socket:setopt(Socket, {otp,recvbuf}, BufSz)
設定。
訊息 Flags
可以是符號 msg_flag/0
和/或 integer/0
,如同平台對應的標頭檔。所有符號標誌和整數的值會進行 OR 運算。
當發生 socket 錯誤時,此函式會傳回 {error, Reason}
,或者如果錯誤發生前已收到部分資料;則傳回 {error, {Reason, Data}}
(僅在 類型 stream
的 socket 中會發生)。
如果 Timeout
參數為 infinity
;則會等待資料到達。對於 類型 stream
的 socket,此呼叫會等到傳送所有請求的資料,或者如果請求了「所有可用」資料,則在第一個資料區塊到達時返回,或者如果作業系統回報操作錯誤時返回。
如果 Timeout
參數為逾時值 (non_neg_integer/0
);如果在 Timeout
毫秒後沒有收到任何資料,則傳回 {error, timeout}
,或者如果在 類型 stream
的 socket 上收到部分但不足夠的資料,則傳回 {error, {timeout, Data}}
。
Timeout = 0
只會輪詢作業系統的接收呼叫,不會啟動非同步呼叫機制。如果沒有可立即使用的資料,則傳回 {error, timeout}
。在 stream
類型的 socket 上,如果沒有可立即使用的足夠資料,則傳回 {error, {timeout, Data}}
。
如果 Handle
參數為 nowait
(自 OTP 22.1 起),則如果無法立即完成操作,則會啟動 非同步呼叫。
如果 Handle
參數是一個 select_handle/0
,(自 OTP 24.0 起),或在 Windows 上,等效的 completion_handle/0
(自 OTP 26.0 起),則像 nowait
一樣啟動一個非同步呼叫。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
在 select
系統上,對於 類型 stream
的 socket,如果 Length > 0
且沒有足夠的可用資料,此函式會傳回 {select, {SelectInfo, Data}}
以及部分 Data
。重複呼叫以完成操作可能需要更新 Length
參數。
-spec recvfrom(Socket :: socket(), Flags :: list()) -> dynamic(); (Socket :: socket(), BufSz :: non_neg_integer()) -> dynamic().
在 socket 上接收訊息。
使用參數 BufSz
;等同於 recvfrom(Socket, BufSz, [], infinity)
。
使用參數 Flags
;等同於 recvfrom(Socket, 0, Flags, infinity)
(自 OTP 24.0 起)。
-spec recvfrom(Socket :: socket(), Flags :: [msg_flag() | integer()], TimeoutOrHandle :: dynamic()) -> dynamic(); (Socket :: socket(), BufSz :: non_neg_integer(), Flags :: [msg_flag() | integer()]) -> dynamic(); (Socket :: socket(), BufSz :: non_neg_integer(), TimeoutOrHandle :: nowait | select_handle() | completion_handle()) -> dynamic().
在 socket 上接收訊息。
使用參數 BufSz
和 Flags
;等同於 recvfrom(Socket, BufSz, Flags, infinity)
。
使用參數 BufSz
和 TimeoutOrHandle
;等同於 recv(Socket, BufSz, [], TimeoutOrHandle)
。
使用參數 Flags
和 TimeoutOrHandle
;等同於 recv(Socket, 0, Flags, TimeoutOrHandle)
TimeoutOrHandle :: 'nowait'
自 OTP 22.1 開始允許。
TimeoutOrHandle :: Handle
自 OTP 24.0 開始允許。
-spec recvfrom(Socket, BufSz, Flags, Timeout :: infinity) -> {ok, {Source, Data}} | {error, Reason} when Socket :: socket(), BufSz :: non_neg_integer(), Flags :: [msg_flag() | integer()], Source :: sockaddr_recv(), Data :: binary(), Reason :: posix() | closed | invalid(); (Socket, BufSz, Flags, Timeout :: non_neg_integer()) -> {ok, {Source, Data}} | {error, Reason} when Socket :: socket(), BufSz :: non_neg_integer(), Flags :: [msg_flag() | integer()], Source :: sockaddr_recv(), Data :: binary(), Reason :: posix() | closed | invalid() | timeout; (Socket, BufSz, Flags, nowait | Handle) -> {ok, {Source, Data}} | {select, SelectInfo} | {completion, CompletionInfo} | {error, Reason} when Socket :: socket(), BufSz :: non_neg_integer(), Flags :: [msg_flag() | integer()], Handle :: select_handle() | completion_handle(), Source :: sockaddr_recv(), Data :: binary(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: posix() | closed | invalid().
在 socket 上接收訊息。
此函式適用於非連線導向的 socket,例如 dgram
或 seqpacket
類型,這些 socket 可能會收到來自不同來源位址的訊息。
參數 BufSz
指定接收緩衝區的位元組數。如果緩衝區大小太小,訊息將會被截斷。
如果 BufSz
為 0
,則會使用預設緩衝區大小,可以使用 socket:setopt(Socket, {otp,recvbuf}, BufSz)
設定。
如果沒有已知適當的緩衝區大小,可以使用接收 訊息標誌 peek
。使用此標誌時,訊息不會從底層緩衝區中「消耗」,因此需要另一個 recvfrom/1,2,3,4
呼叫,可能需要調整緩衝區大小。
訊息 Flags
可以是符號 msg_flag/0
和/或 integer/0
,如同平台對應的標頭檔。所有符號標誌和整數的值會進行 OR 運算。
如果 Timeout
參數為 infinity
;則會等待訊息到達或發生 socket 錯誤。
如果 Timeout
參數為逾時值 (non_neg_integer/0
);如果在 Timeout
毫秒後沒有收到任何訊息,則傳回 {error, timeout}
。
Timeout = 0
只會輪詢作業系統的接收呼叫,不會啟動非同步呼叫機制。如果沒有可立即使用的訊息,則傳回 {error, timeout}
。
如果 Handle
參數為 nowait
(自 OTP 22.1 起),則如果無法立即完成操作,則會啟動 非同步呼叫。
如果 'Handle' 參數為 select_handle/0
,(自 OTP 24.0 起),或者在 Windows 上,為等效的 completion_handle/0
(自 OTP 26.0 起),則會啟動 非同步呼叫,就像 nowait
一樣。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
-spec recvmsg(Socket :: socket(), Flags :: list()) -> dynamic(); (Socket :: socket(), TimeoutOrHandle :: reference() | infinity | nowait | non_neg_integer()) -> dynamic().
在 socket 上接收訊息。
使用參數 Flags
;等同於 recvmsg(Socket, 0, 0, Flags, infinity)
。
使用參數 TimeoutOrHandle
;等同於 recvmsg(Socket, 0, 0, [], TimeoutOrHandle)
。
TimeoutOrHandle :: nowait
自 OTP 22.1 開始允許。
TimeoutOrHandle :: Handle
自 OTP 24.0 開始允許。
-spec recvmsg(Socket :: dynamic(), Flags :: list(), TimeoutOrHandle :: dynamic()) -> dynamic(); (Socket :: dynamic(), BufSz :: integer(), CtrlSz :: integer()) -> dynamic().
在 socket 上接收訊息。
使用參數 Flags
;等同於 recvmsg(Socket, 0, 0, Flags, infinity)
。
使用參數 TimeoutOrHandle
;等同於 recvmsg(Socket, 0, 0, [], TimeoutOrHandle)
。
TimeoutOrHandle :: nowait
自 OTP 22.1 開始允許。
TimeoutOrHandle :: Handle
自 OTP 24.0 開始允許。
-spec recvmsg(Socket :: socket(), BufSz :: non_neg_integer(), CtrlSz :: non_neg_integer(), TimeoutOrHandle :: dynamic()) -> dynamic().
-spec recvmsg(Socket, BufSz, CtrlSz, Flags, Timeout :: infinity) -> {ok, Msg} | {error, Reason} when Socket :: socket(), BufSz :: non_neg_integer(), CtrlSz :: non_neg_integer(), Flags :: [msg_flag() | integer()], Msg :: msg_recv(), Reason :: posix() | closed | invalid(); (Socket, BufSz, CtrlSz, Flags, Timeout :: non_neg_integer()) -> {ok, Msg} | {error, Reason} when Socket :: socket(), BufSz :: non_neg_integer(), CtrlSz :: non_neg_integer(), Flags :: [msg_flag() | integer()], Msg :: msg_recv(), Reason :: posix() | closed | invalid() | timeout; (Socket, BufSz, CtrlSz, Flags, nowait | Handle) -> {ok, Msg} | {select, SelectInfo} | {completion, CompletionInfo} | {error, Reason} when Socket :: socket(), BufSz :: non_neg_integer(), CtrlSz :: non_neg_integer(), Handle :: select_handle() | completion_handle(), Flags :: [msg_flag() | integer()], Msg :: msg_recv(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: posix() | closed | invalid().
在 socket 上接收訊息。
此函式接收資料和控制訊息。
參數 BufSz
和 CtrlSz
指定接收緩衝區和控制訊息緩衝區的位元組數。如果緩衝區大小太小,訊息和/或控制訊息清單將被截斷。
如果 BufSz
為 0
,則會使用預設緩衝區大小,該大小可由 socket:setopt(Socket, {otp,recvbuf}, BufSz)
設定。同樣適用於 CtrlSz
和 socket:setopt(Socket, {otp,recvctrlbuf}, CtrlSz)
。
如果沒有已知適當的緩衝區大小,可以使用接收 訊息標誌 peek
。使用此標誌時,訊息不會從底層緩衝區中「消耗」,因此需要另一個 recvfrom/1,2,3,4
呼叫,可能需要調整緩衝區大小。
訊息 Flags
可以是符號 msg_flag/0
和/或 integer/0
,如同平台對應的標頭檔。所有符號標誌和整數的值會進行 OR 運算。
如果 Timeout
參數為 infinity
,則會等待訊息到達,或等待發生 socket 錯誤。
如果 Timeout
參數為逾時值(non_neg_integer/0
),如果在 Timeout
毫秒後沒有收到任何訊息,則會傳回 {error, timeout}
。
Timeout = 0
只會輪詢作業系統的接收呼叫,不會啟動非同步呼叫機制。如果沒有可立即使用的訊息,則傳回 {error, timeout}
。
如果 Handle
參數為 nowait
(自 OTP 22.1 起),則如果無法立即完成操作,則會啟動 非同步呼叫。
如果 'Handle' 參數為 select_handle/0
,(自 OTP 24.0 起),或者在 Windows 上,為等效的 completion_handle/0
(自 OTP 26.0 起),則會啟動 非同步呼叫,就像 nowait
一樣。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
-spec send(Socket :: term(), Data :: term(), Cont :: tuple()) -> _; (Socket :: term(), Data :: term(), Flags :: list()) -> _; (Socket :: term(), Data :: term(), Timeout :: timeout()) -> _.
在連線的 socket 上傳送資料。
使用參數 Timeout
,等同於 send(Socket, Data, [], Timeout)
。
使用參數 Flags
,等同於 send(Socket, Data, Flags, infinity)
。
使用參數 Cont
,等同於 send(Socket, Data, Cont, infinity)
(自 OTP 24.0 起)。
-spec send(Socket, Data, Flags | Cont, Timeout :: infinity) -> ok | {ok, RestData} | {error, Reason} | {error, {Reason, RestData}} when Socket :: socket(), Data :: iodata(), Flags :: [msg_flag() | integer()], Cont :: select_info(), RestData :: binary(), Reason :: posix() | closed | invalid() | netname_deleted | too_many_cmds | eei(); (Socket, Data, Flags | Cont, Timeout :: non_neg_integer()) -> ok | {ok, RestData} | {error, Reason | timeout} | {error, {Reason | timeout, RestData}} when Socket :: socket(), Data :: iodata(), Flags :: [msg_flag() | integer()], Cont :: select_info(), RestData :: binary(), Reason :: posix() | closed | invalid() | netname_deleted | too_many_cmds | eei(); (Socket, Data, Flags | Cont, nowait | Handle) -> ok | {ok, RestData} | {select, SelectInfo} | {select, {SelectInfo, RestData}} | {completion, CompletionInfo} | {error, Reason} when Socket :: socket(), Data :: iodata(), Flags :: [msg_flag() | integer()], Cont :: select_info(), Handle :: select_handle() | completion_handle(), RestData :: binary(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: posix() | closed | invalid() | netname_deleted | too_many_cmds | eei().
在連線的 socket 上傳送資料。
訊息 Flags
可以是符號 msg_flag/0
和/或 integer/0
,如同平台對應的標頭檔。所有符號標誌和整數的值會進行 OR 運算。
如果 Data
不是 binary/0
,則在呼叫平台網路 API 之前,會將其複製到一個二進位資料中,因為需要單一緩衝區。傳回的 RestData
是它的子二進位資料。
傳回值表示來自平台網路層的結果。
ok
- 所有資料都被作業系統接受以進行傳遞。{ok, RestData}
- 接受了部分但並非全部的資料,但沒有回報錯誤(部分成功傳送)。RestData
是Data
中未被接受的尾部。對於 類型
stream
的 socket,不會發生這種情況,其中部分成功的傳送會重試,直到資料被接受傳遞或發生錯誤。對於 類型
dgram
的 socket,這也可能不應該發生,因為無法以原子方式傳遞的訊息應該會產生錯誤。然而,平台的網路層仍有可能傳回此值,對於 類型
seqpacket
的 socket 來說,這種情況更可能發生。{error, Reason}
- 回報了錯誤,且沒有接受任何資料進行傳遞。Reason :: posix/0
是平台網路層回報的。closed
表示這個 socket 程式庫被告知 socket 已關閉,而invalid/0
表示這個 socket 程式庫發現參數無效。{error, {Reason, RestData}}
- 回報了錯誤,但在那之前已接受部分資料進行傳遞。RestData
是Data
中未被接受的尾部。請參閱上面的{error, Reason}
。只有當 類型
stream
的 socket 在重試部分成功的傳送直到發生錯誤時,才會發生這種情況。
如果 Timeout
參數為 infinity
,則會等待作業系統完成傳送操作(承擔資料責任),或傳回錯誤。
如果 Timeout
參數為逾時值(non_neg_integer/0
),如果在 Timeout
毫秒內沒有傳送任何資料,則會傳回 {error, timeout}
;如果已傳送部分資料(被作業系統接受以進行傳遞),則會傳回 {error, {timeout, RestData}}
。RestData
是未傳送的資料尾部。
如果 Handle
參數為 nowait
(自 OTP 22.1 起),則如果無法立即完成操作,則會啟動 非同步呼叫。
如果 Handle
參數是一個 select_handle/0
,(自 OTP 24.0 起),或在 Windows 上,等效的 completion_handle/0
(自 OTP 26.0 起),則像 nowait
一樣啟動一個非同步呼叫。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
如果使用 Cont
參數呼叫此函數,也就是先前 send/3,4
呼叫中的 SelectInfo
,則會使用 SelectInfo
中預先處理的傳送參數繼續傳送。使用此參數變體可以避免例如在每次呼叫(除了第一次呼叫)時都必須驗證和編碼訊息旗標。
-spec sendfile(Socket, FileHandle | Continuation) -> dynamic() when Socket :: socket(), FileHandle :: file:fd(), Continuation :: select_info().
在 socket 上傳送檔案。
等同於 sendfile(Socket, FileHandle_or_Continuation, 0, 0, infinity)
。
-spec sendfile(Socket, FileHandle | Continuation, Timeout | Handle) -> dynamic() when Socket :: socket(), FileHandle :: file:fd(), Continuation :: select_info(), Timeout :: infinity | non_neg_integer(), Handle :: nowait | select_handle().
在 socket 上傳送檔案。
等同於 sendfile(Socket, FileHandle_or_Continuation, 0, 0, Timeout_or_Handle)
。
-spec sendfile(Socket, FileHandle | Continuation, Offset, Count) -> dynamic() when Socket :: socket(), FileHandle :: file:fd(), Continuation :: select_info(), Offset :: integer(), Count :: non_neg_integer().
在 socket 上傳送檔案。
等同於 sendfile(Socket, FileHandle_or_Continuation, Offset, Count, infinity)
。
-spec sendfile(Socket, FileHandle | Continuation, Offset, Count, Timeout :: infinity) -> {ok, BytesSent} | {error, Reason} | {error, {Reason, BytesSent}} when Socket :: socket(), FileHandle :: file:fd(), Continuation :: select_info(), Offset :: integer(), Count :: non_neg_integer(), BytesSent :: non_neg_integer(), Reason :: posix() | closed | invalid(); (Socket, FileHandle | Continuation, Offset, Count, Timeout :: non_neg_integer()) -> {ok, BytesSent} | {error, Reason} | {error, {Reason, BytesSent}} when Socket :: socket(), FileHandle :: file:fd(), Continuation :: select_info(), Offset :: integer(), Count :: non_neg_integer(), BytesSent :: non_neg_integer(), Reason :: posix() | closed | invalid() | timeout; (Socket, FileHandle | Continuation, Offset, Count, nowait | (SelectHandle :: select_handle())) -> {ok, BytesSent} | {select, SelectInfo} | {select, {SelectInfo, BytesSent}} | {error, Reason} when Socket :: socket(), FileHandle :: file:fd(), Continuation :: select_info(), Offset :: integer(), Count :: non_neg_integer(), BytesSent :: non_neg_integer(), SelectInfo :: select_info(), Reason :: posix() | closed | invalid().
在 socket 上傳送檔案。
注意
此函數在 Windows 上不受支援。
FileHandle
參數必須參照 file:open/2
中所述的已開啟原始檔案。
Offset
參數是要開始讀取的檔案偏移量。預設偏移量為 0
。
Count
參數是要從 FileHandle
傳輸到 Socket
的位元組數。如果 Count = 0
(預設值),則傳輸會在檔案結尾停止。
傳回值表示來自平台網路層的結果。
{ok, BytesSent}
- 在BytesSent
個位元組的資料之後,傳輸成功完成。{error, Reason}
- 已回報錯誤,且沒有傳輸任何資料。Reason :: posix/0
是平台網路層回報的。closed
表示這個 socket 程式庫被告知 socket 已關閉,而invalid/0
表示這個 socket 程式庫發現參數無效。{error, {Reason, BytesSent}}
- 已回報錯誤,但在那之前已傳輸部分資料。請參閱上面的{error, Reason}
和{ok, BytesSent}
。
如果 Timeout
參數為 infinity
,則會等待作業系統完成傳送操作(承擔資料責任),或傳回錯誤。
如果 Timeout
參數為逾時值(non_neg_integer/0
),如果在 Timeout
毫秒內沒有傳送任何資料,則會傳回 {error, timeout}
;如果已傳送部分但並非全部資料(被作業系統接受以進行傳遞),則會傳回 {error, {timeout, BytesSent}}
。
如果 Handle
參數為 nowait
,如果無法立即完成操作,則會啟動一個非同步呼叫。
如果 Handle
參數為 select_handle/0
,則會像 nowait
一樣啟動一個非同步呼叫。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
在收到 select
訊息後,使用 SelectInfo
作為 Continuation
參數呼叫 sendfile/2,3,4,5
,以完成操作。
如果使用 Continuation
參數呼叫此函數,也就是先前 sendfile/5
呼叫中的 SelectInfo
,則會使用 SelectInfo
中預先處理的參數繼續傳輸。
Offset
和可能 Count
參數可能需要在連續呼叫之間更新。
-spec sendmsg(Socket, Msg) -> Result when Socket :: socket(), Msg :: msg_send() | erlang:iovec(), Result :: dynamic().
-spec sendmsg(Socket :: socket(), Msg :: msg_send(), Flags :: list()) -> dynamic(); (Socket :: socket(), Data :: msg_send() | erlang:iovec(), Cont :: select_info()) -> dynamic(); (Socket :: socket(), Msg :: msg_send(), Timeout :: infinity) -> dynamic().
在 socket 上傳送資料和控制訊息。
使用參數 Msg
和 Timeout
,等同於 sendmsg(Socket, Msg, [], Timeout)
。
使用參數 Msg
和 Flags
,等同於 sendmsg(Socket, Msg, Flags, infinity)
。
使用參數 Data
和 Cont
,等同於 sendmsg(Socket, Data, Cont, infinity)
(自 OTP 24.0 起)。
-spec sendmsg(Socket, Msg, Flags, Timeout :: infinity) -> ok | {ok, RestData} | {error, Reason} | {error, {Reason, RestData}} when Socket :: socket(), Msg :: msg_send(), Flags :: [msg_flag() | integer()], RestData :: erlang:iovec(), Reason :: posix() | closed | invalid(); (Socket, Msg, Flags, Timeout :: non_neg_integer()) -> ok | {ok, RestData} | {error, Reason | timeout} | {error, {Reason | timeout, RestData}} when Socket :: socket(), Msg :: msg_send(), Flags :: [msg_flag() | integer()], RestData :: erlang:iovec(), Reason :: posix() | closed | invalid(); (Socket, Msg, Flags, nowait | Handle) -> ok | {ok, RestData} | {select, SelectInfo} | {select, {SelectInfo, RestData}} | {completion, CompletionInfo} | {error, Reason} | {error, {Reason, RestData}} when Socket :: socket(), Msg :: msg_send(), Flags :: [msg_flag() | integer()], Handle :: select_handle() | completion_handle(), RestData :: erlang:iovec(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: posix() | closed | invalid(); (Socket, Data, Cont, Timeout :: infinity) -> ok | {ok, RestData} | {error, Reason} | {error, {Reason, RestData}} when Socket :: socket(), Data :: msg_send() | erlang:iovec(), Cont :: select_info(), RestData :: erlang:iovec(), Reason :: posix() | closed | invalid(); (Socket, Data, Cont, Timeout :: non_neg_integer()) -> ok | {ok, RestData} | {error, Reason | timeout} | {error, {Reason | timeout, RestData}} when Socket :: socket(), Data :: msg_send() | erlang:iovec(), Cont :: select_info(), RestData :: erlang:iovec(), Reason :: posix() | closed | invalid(); (Socket, Data, Cont, nowait | Handle) -> ok | {ok, RestData} | {select, SelectInfo} | {select, {SelectInfo, RestData}} | {completion, CompletionInfo} | {error, Reason} | {error, {Reason, RestData}} when Socket :: socket(), Data :: msg_send() | erlang:iovec(), Cont :: select_info(), Handle :: select_handle(), RestData :: erlang:iovec(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: posix() | closed | invalid().
在 socket 上傳送資料和控制訊息。
參數 Msg
是一個 map,其中包含要傳送的資料,該資料在 iov
鍵下作為 erlang:iovec/0
(binary/0
清單)。它也可以在 addr
鍵下包含目的地地址,如果 socket 未連線,則此為必要條件。如果 socket 已連線,最好不要有 addr
鍵,因為平台可能會將其視為錯誤(或忽略它)。在 ctrl
鍵下,可以有一個協定和平台相依的控制訊息清單(又名輔助資料,又名控制資訊)要傳送。
訊息資料會以 I/O 向量的形式提供給平台的網路層,而不會複製內容。如果 I/O 向量中的元素數量大於平台上允許的數量(在 info/0
的 iov_max
欄位中回報),則在 類型 stream
的 socket 上,傳送會在所有元素上迭代,但對於其他 socket 類型,呼叫會失敗。
請參閱 send/4
以取得 Flags
參數和傳回值的說明。
注意
在 Windows 上,此函數只能用於資料包和原始 socket。
如果 Timeout
參數為 infinity
,則會等待作業系統完成傳送操作(承擔資料責任),或傳回錯誤。
如果 Timeout
參數為逾時值(non_neg_integer/0
),如果在 Timeout
毫秒內沒有傳送任何資料,則會傳回 {error, timeout}
;如果已傳送部分資料(被作業系統接受以進行傳遞),則會傳回 {error, {timeout, RestData}}
。RestData
是未傳送的資料尾部。
如果 Handle
參數為 nowait
(自 OTP 22.1 起),則如果無法立即完成操作,則會啟動 非同步呼叫。
如果 Handle
參數是一個 select_handle/0
,(自 OTP 24.0 起),或在 Windows 上,等效的 completion_handle/0
(自 OTP 26.0 起),則像 nowait
一樣啟動一個非同步呼叫。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
在收到 select
訊息後,使用 SelectInfo
作為 Cont
參數呼叫 sendmsg/3,4
,以完成操作。
使用參數 Data
和 Cont
,繼續傳送操作。Cont
應該是從先前 sendmsg/2,3,4
呼叫傳回的 SelectInfo
。
Data
可以是 Msg
map/0
,其中僅使用 iov
鍵,或是 erlang:iovec/0
。
-spec sendto(Socket :: socket(), Data :: iodata(), Cont | Dest) -> Result when Cont :: select_info(), Dest :: sockaddr(), Result :: ok | {ok, RestData} | {error, Reason} | {error, {Reason, RestData}}, RestData :: binary(), Reason :: posix() | closed | invalid().
在 socket 上傳送資料。
使用參數 Dest
,等同於 sendto(Socket, Data, Dest, [], infinity)
。
使用參數 Cont
,等同於 sendto(Socket, Data, Cont, infinity)
(自 OTP 24.0 起)。
-spec sendto(Socket :: socket(), Data :: iodata(), Dest :: sockaddr(), Flags :: list()) -> Result when Result :: ok | {ok, RestData :: binary()} | {error, Reason} | {error, {Reason, RestData :: binary()}}, Reason :: posix() | closed | invalid(); (Socket :: socket(), Data :: iodata(), Cont :: select_info(), TimeoutOrHandle :: dynamic()) -> Result when Result :: ok | {ok, RestData :: binary()} | {error, Reason} | {error, {Reason, RestData :: binary()}}, Reason :: posix() | closed | invalid().
在 socket 上傳送資料。
使用參數 Dest
和 TimeoutOrHandle
;等同於 sendto(Socket, Data, Dest, [], TimeoutOrHandle)
。
使用參數 Dest
和 Flags
;等同於 sendto(Socket, Data, Dest, Flags, infinity)
。
使用參數 Cont
和 TimeoutOrHandle
;Cont
必須是前一次 sendto/3,4,5
呼叫的 SelectInfo
,並使用 SelectInfo
中預處理的發送參數繼續發送。使用此參數變體可以避免,例如在每次呼叫中都驗證和編碼訊息標誌,只需在第一次呼叫時執行即可。(自 OTP 24.0 起)
請參閱 sendto/5
的最後一個參數(參數 5),以了解 TimeoutOrHandle
的說明。
-spec sendto(Socket, Data, Dest, Flags, Timeout :: infinity) -> ok | {ok, RestData} | {error, Reason} | {error, {Reason, RestData}} when Socket :: socket(), Data :: iodata(), Dest :: sockaddr(), Flags :: [msg_flag() | integer()], RestData :: binary(), Reason :: posix() | closed | invalid(); (Socket, Data, Dest, Flags, Timeout :: non_neg_integer()) -> ok | {ok, RestData} | {error, Reason | timeout} | {error, {Reason | timeout, RestData}} when Socket :: socket(), Data :: iodata(), Dest :: sockaddr(), Flags :: [msg_flag() | integer()], RestData :: binary(), Reason :: posix() | closed | invalid(); (Socket, Data, Dest, Flags, nowait | Handle) -> ok | {ok, RestData} | {select, SelectInfo} | {select, {SelectInfo, RestData}} | {completion, CompletionInfo} | {error, Reason} when Socket :: socket(), Data :: iodata(), Dest :: sockaddr(), Flags :: [msg_flag() | integer()], Handle :: select_handle() | completion_handle(), RestData :: binary(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: posix() | closed | invalid().
在 socket 上傳送資料。
To
參數是要發送資料的目的地地址。對於已連線的 socket,此參數仍然會傳遞給作業系統呼叫,該呼叫可能會忽略該地址或返回錯誤。
請參閱 send/4
以了解 Flags
和 Data
參數以及傳回值的說明。
如果 Timeout
參數為 infinity
,則會等待作業系統完成傳送操作(承擔資料責任),或傳回錯誤。
如果 Timeout
參數為逾時值(non_neg_integer/0
),如果在 Timeout
毫秒內沒有傳送任何資料,則會傳回 {error, timeout}
;如果已傳送部分資料(被作業系統接受以進行傳遞),則會傳回 {error, {timeout, RestData}}
。RestData
是未傳送的資料尾部。
如果 Handle
參數為 nowait
(自 OTP 22.1 起),則如果無法立即完成操作,則會啟動 非同步呼叫。
如果 Handle
參數是一個 select_handle/0
,(自 OTP 24.0 起),或在 Windows 上,等效的 completion_handle/0
(自 OTP 26.0 起),則像 nowait
一樣啟動一個非同步呼叫。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
在收到 select
訊息後,使用 SelectInfo
作為 Cont
參數呼叫 sendto/3,4
,以完成操作。
-spec sendv(Socket, IOV) -> ok | {ok, RestIOV} | {error, Reason} | {error, {Reason, RestIOV}} when Socket :: socket(), IOV :: erlang:iovec(), RestIOV :: erlang:iovec(), Reason :: posix() | closed | invalid().
-spec sendv(Socket, IOV, Timeout :: infinity) -> ok | {ok, RestIOV} | {error, Reason} | {error, {Reason, RestIOV}} when Socket :: socket(), IOV :: erlang:iovec(), RestIOV :: erlang:iovec(), Reason :: posix() | closed | invalid(); (Socket, IOV, Timeout :: non_neg_integer()) -> ok | {ok, RestIOV} | {error, Reason} | {error, {Reason, RestIOV}} when Socket :: socket(), IOV :: erlang:iovec(), RestIOV :: erlang:iovec(), Reason :: posix() | closed | invalid() | timeout; (Socket, IOV, nowait | Handle) -> ok | {ok, RestIOV} | {select, SelectInfo} | {select, {SelectInfo, RestIOV}} | {completion, CompletionInfo} | {error, Reason} | {error, {Reason, RestIOV}} when Socket :: socket(), IOV :: erlang:iovec(), Handle :: select_handle() | completion_handle(), RestIOV :: erlang:iovec(), SelectInfo :: select_info(), CompletionInfo :: completion_info(), Reason :: posix() | closed | invalid(); (Socket, IOV, Cont) -> ok | {ok, RestIOV} | {error, Reason} | {error, {Reason, RestIOV}} when Socket :: socket(), IOV :: erlang:iovec(), Cont :: select_info(), RestIOV :: erlang:iovec(), Reason :: posix() | closed | invalid().
在連線的 socket 上傳送 erlang:iovec/0
資料。
請參閱 sendmsg/4
,了解如何將 IOV
資料傳遞到平台的網路層。
傳回值表示來自平台網路層的結果。
ok
- 所有資料已被作業系統接受以進行傳遞。{ok, RestIOV}
- 部分但不是全部的資料被接受,但沒有回報錯誤(部分成功發送)。RestIOV
是IOV
中未被接受的部分。{error, Reason}
- 回報了一個錯誤,並且沒有任何資料被接受以進行傳遞。Reason :: posix/0
是平台網路層回報的內容。closed
表示此 socket 函式庫被告知 socket 已關閉,而invalid/0
表示此 socket 函式庫發現參數無效。{error, {Reason, RestIOV}}
- 回報了一個錯誤,但在那之前,有些資料已被接受以進行傳遞。RestIOV
是IOV
中未被接受的部分。請參閱上方的{error, Reason}
。
如果 Timeout
參數為 infinity
,則會等待作業系統完成傳送操作(承擔資料責任),或傳回錯誤。
如果 Timeout
參數是一個逾時值(non_neg_integer/0
);如果在 Timeout
毫秒內沒有發送任何資料,則傳回 {error, timeout}
,或者如果發送了一些資料(已被作業系統接受以進行傳遞),則傳回 {error, {timeout, RestIOV}}
。RestIOV
是尚未發送的資料尾部。
如果 Handle
參數為 nowait
,如果無法立即完成操作,則會啟動一個非同步呼叫。
如果 Handle
參數是一個 select_handle/0
,或者在 _Windows_ 上,是等效的 completion_handle/0
,則會像 nowait
一樣啟動一個非同步呼叫。
請參閱此模組參考手冊頁面開頭的 非同步呼叫 說明。
使用參數 Cont
,等同於 sendv(Socket, IOV, Cont, infinity)
。
-spec sendv(Socket, IOV, Cont, Timeout :: infinity) -> ok | {ok, RestIOV} | {error, Reason} | {error, {Reason, RestIOV}} when Socket :: socket(), IOV :: erlang:iovec(), Cont :: select_info(), RestIOV :: erlang:iovec(), Reason :: posix() | closed | invalid(); (Socket, IOV, Cont, Timeout :: non_neg_integer()) -> ok | {ok, RestIOV} | {error, Reason} | {error, {Reason | RestIOV}} when Socket :: socket(), IOV :: erlang:iovec(), Cont :: select_info(), RestIOV :: erlang:iovec(), Reason :: posix() | closed | invalid() | timeout; (Socket, IOV, Cont, nowait | SelectHandle) -> ok | {ok, RestIOV} | {select, SelectInfo} | {select, {SelectInfo, RestIOV}} | {error, Reason} | {error, {Reason, RestIOV}} when Socket :: socket(), IOV :: erlang:iovec(), Cont :: select_info(), SelectHandle :: select_handle(), RestIOV :: erlang:iovec(), SelectInfo :: select_info(), Reason :: posix() | closed | invalid().
在連線的 socket 上傳送資料,接續。
繼續在已連線的 socket 上發送資料。Cont
是前一次 sendv/2,3
呼叫傳回的 SelectInfo
。IOV
應該是未發送的剩餘資料。
請參閱 非同步呼叫,了解如何繼續未完成的呼叫。
請參閱 sendv/3
以了解傳回值。
-spec setopt(Socket, SocketOption, Value) -> ok | {error, invalid() | closed} when Socket :: socket(), SocketOption :: {Level :: otp, Opt :: otp_socket_option()}, Value :: dynamic(); (Socket, SocketOption, Value) -> ok | {error, posix() | invalid() | closed} when Socket :: socket(), SocketOption :: socket_option(), Value :: dynamic().
設定 socket 選項。
設定作業系統協定層級選項,或 otp
偽協定層級選項。後者層級是此模組在作業系統協定層級之上的實作層級。
有關 otp
協定層級的說明,請參閱類型 otp_socket_option() 。
有關此實作知道哪些作業系統協定層級選項、它們如何與作業系統選項名稱相關聯,以及它們是否有任何已知的特性,請參閱類型 socket_option/0
。
哪些選項有效取決於作業系統,以及 Socket 的類型(domain/0
、type/0
和 protocol/0
)。詳情請參閱 t:socket_option()
類型以及使用者指南中的 Socket 選項章節。
注意
並非所有選項在所有平台上都有效或可以設定。也就是說,即使此
socket
實作支援某個選項;也不表示底層作業系統也支援。
設定 socket 選項(為了向後相容的函數)。
等同於 setopt(Socket, {Level, Opt}, Value)
,或者作為特殊情況,如果 Opt = NativeOpt ::
integer/0
且 Value =
binary/0
,則等同於 setopt_native(Socket, {Level, NativeOpt}, ValueSpec)
。
請改用 setopt/3
或 setopt_native/3
來將選項層級和名稱作為單一項處理,並清楚區分已知選項和原生選項。
-spec setopt_native(Socket, Option, Value) -> ok | {error, posix() | invalid() | closed} when Socket :: socket(), Option :: socket_option() | {Level, NativeOpt} | {NativeLevel, NativeOpt}, Value :: native_value(), Level :: level(), NativeLevel :: integer(), NativeOpt :: integer().
設定「原生」socket 選項。
設定我們的實作可能不認識的 socket 選項,或者具有與我們的實作不相容的類型,也就是說;在「原生模式」中。
如果 Value
是一個 integer/0
,它將被用作 C
類型 (int)
,如果它是一個 boolean/0
,它將被用作 C
類型 (int)
,並使用 C
實作的 false
或 true
值,如果它是一個 binary/0
,則其內容和大小將被用作選項值。
socket 選項可以指定為普通的 socket_option/0
tuple,使用符號 Level
作為 {
Level :: level/0
,
NativeOpt :: integer/0
}
,或使用整數表示 NativeLevel
和 NativeOpt
,如 {
NativeLevel :: integer/0
,
NativeOpt :: integer/0
}
。
選項是否有效取決於平台以及 Socket 的類型(domain/0
、type/0
和 protocol/0
)。
NativeLevel
和 NativeOpt
的整數值以及 Value
編碼必須從正在執行的系統的標頭檔中推斷出來。
-spec shutdown(Socket, How) -> ok | {error, Reason} when Socket :: socket(), How :: read | write | read_write, Reason :: posix() | closed.
關閉全雙工連線的全部或一部分。
-spec sockname(Socket :: socket()) -> {ok, SockAddr} | {error, Reason} when SockAddr :: sockaddr_recv(), Reason :: posix() | closed.
取得 socket 的位址。
傳回目前 socket 繫結的地址。如果繫結地址具有萬用字元埠 0
,則此函式傳回的地址包含作業系統選取的暫時埠。
-spec supports() -> [{Key1 :: term(), boolean() | [{Key2 :: term(), boolean() | [{Key3 :: term(), boolean()}]}]}].
檢索關於模組和平台支援哪些 socket 功能的資訊。
傳回一個清單,其中包含所有在 supports/1
中描述的 Key1
的 {Key1,
supports(Key1)
}
tuple,並且不按特定順序排列,以及以下每個 key 的 {Key, boolean()}
tuple
sctp
- SCTP 支援ipv6
- IPv6 支援local
- Unix 網域 socket 支援 (AF_UNIX | AF_LOCAL
)netns
- 網路命名空間支援 (Linux,setns(2)
)sendfile
- Sendfile 支援 (sendfile(2)
)
檢索關於模組和平台支援哪些 socket 功能的資訊。
如果 Key1 = msg_flags
,則會針對 msg_flag/0
中的每個 Flag
傳回 {Flag, boolean()}
tuple 的清單,其中 boolean/0
指示此平台上是否支援該標誌。
如果 Key1 = protocols
,則會針對 protocol/0
中的每個 Name
傳回 {Name, boolean()}
tuple 的清單,其中 boolean/0
指示此平台上是否支援該協定。
如果 Key1 = options
,則會針對 socket_option/0
中的每個 SocketOption
傳回 {SocketOption, boolean()}
tuple 的清單,其中 boolean/0
指示此平台上是否支援該 socket 選項。
傳回的任何清單都沒有特定的順序。
對於 Key1
的其他值,傳回 []
。請注意,在此模組的未來版本或在不同的平台上,可能會支援更多的 key。
檢索關於模組和平台支援哪些 socket 功能的資訊。
如果 Key1 = options
,對於 level/0
中的 Key2
,會傳回一個 {Opt, boolean()}
tuple 的清單,其中包含在該 Level = Key2
上的所有已知的 socket 選項 Opt
,其中 boolean/0
指示此平台上是否支援該 socket 選項。請參閱 setopt/3
和 getopt/2
。
傳回的任何清單都沒有特定的順序。
對於 Key1
或 Key2
的其他值,傳回 []
。請注意,在此模組的未來版本或在不同的平台上,可能會支援更多的 key。
-spec use_registry(D :: boolean()) -> ok.
設定全域 use_registry
選項預設值。
全域變更是否使用 socket 註冊表。請注意,在建立個別 socket 時仍然可以明確地覆寫此設定,詳見 open/2,3,4
( Opts :: map/0
)。
-spec which_sockets() -> [socket()].
傳回所有已知 socket 的清單。
-spec which_sockets(FilterRule) -> [socket()] when FilterRule :: inet | inet6 | local | stream | dgram | seqpacket | sctp | tcp | udp | pid() | fun((socket_info()) -> boolean()).
傳回已篩選的已知 socket 清單。
有幾個預定義的 FilterRule
以及一個通用規則
inet | inet6
- 僅返回具有相符domain/0
的 sockets。stream | dgram | seqpacket
- 僅返回具有相符type/0
的 sockets。sctp | tcp | udp
- 僅返回具有相符protocol/0
的 sockets。pid/0
- 僅返回具有相符控制程序的 sockets。請參閱 OTP socket 選項controlling_process
。fun((socket_info()) -> boolean())
- 通用篩選規則。一個接收 socket 資訊並返回boolean/0
以指示是否應返回該 socket 的函式。