查看源代码 socket (内核 v10.2)
套接字接口。
此模块为网络套接字提供 API。提供了创建、删除和操作套接字以及在其上发送和接收数据的函数。
其目的是尽可能地“接近”操作系统级别的套接字接口。唯一显著的补充是一些函数(例如 recv/3
)具有超时参数。
注意
异步调用
某些函数具有异步调用。这是通过将
Timeout
参数设置为nowait
或Handle ::
reference/0
来实现的。请参阅相应函数的类型规范。此模块有两种不同的异步调用实现。一种是在 Unix 系列操作系统上:
select
- 基于标准套接字接口的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
的套接字,可能会发生这种情况,其中流处理可以在任何点拆分数据流。请参阅相应函数的类型规范的返回类型。
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
和接收到的select
消息中的SelectHandle
,或返回的completion_info/0
和接收到的completion
消息中的CompletionHandle
。然后,编译器可以优化后续的
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}
后,accept 操作已完成。请注意,这里存在竞争;无法知道调用是在发送
select
消息之前重复的,因为它可能刚好在重复调用之前发送。因此,现在收件箱中可能有一条包含Handle
的select
消息。
abort
消息用户必须准备好的另一个消息(当使用
nowait | Handle
时)是abort
消息
{'$socket',
Socket
, abort, Info}
此消息表示正在进行的操作已中止。例如,如果套接字已由另一个进程关闭;
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 handle)API 功能可以被认为不再是实验性的。 - 在 OTP 27.0 中,Windows 风格的(completion handle)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
套接字选项。
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
根据此模块的套接字。
一个 map/0
,包含 名称 := 计数器
的关联。
对于套接字唯一的、不透明的套接字句柄。
套接字选项。
C:struct timeval
协议类型。
函数
在监听套接字上接受连接。
将名称绑定到套接字。
取消正在进行的异步调用。
取消套接字监视器。
关闭套接字。
完成 connect/3
操作。
将套接字连接到给定地址。
获取套接字选项的值。
获取套接字选项(向后兼容函数)。
获取“原生”套接字选项。
以表格格式将所有套接字的信息打印到 erlang shell。
以表格格式将所有套接字的信息打印到 erlang shell。
以表格格式将选定套接字的信息打印到 erlang shell。
获取有关此 socket
库的杂项信息。
获取有关套接字的杂项信息。
设置套接字(设备)参数。
获取或设置套接字(设备)参数。
设置套接字(设备)参数。
检查是否支持某个套接字功能。
检查是否支持某个套接字功能。
使套接字监听连接。
使套接字监听连接。
启动套接字监视器。
返回活动套接字的数量。
等效于 open(FD, #{})
。
创建套接字。
创建套接字。
返回套接字的远程地址。
在连接的套接字上接收数据。
在连接的套接字上接收数据。
在连接的套接字上接收数据。
在套接字上接收消息。
在套接字上接收消息。
在套接字上接收消息。
在套接字上接收消息。
在套接字上接收消息。
在套接字上接收消息。
在连接的套接字上发送数据。
在连接的套接字上发送数据。
在套接字上发送文件。
在套接字上发送文件。
在套接字上发送数据和控制消息。
在套接字上发送数据和控制消息。
在套接字上发送数据。
在套接字上发送数据。
在套接字上发送数据。
在连接的套接字上发送 erlang:iovec/0
数据。
在连接的套接字上发送数据,续传。
设置套接字选项。
设置套接字选项(向后兼容函数)。
设置“原生”套接字选项。
关闭全双工连接的全部或部分。
获取套接字的地址。
检索有关模块和平台支持的套接字功能的信息。
检索有关模块和平台支持的套接字功能的信息。
检索有关模块和平台支持的套接字功能的信息。
设置全局 use_registry
选项默认值。
返回所有已知套接字的列表。
返回已知套接字的过滤列表。
类型
控制消息(辅助消息)。
-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
返回的控制消息(辅助消息)。
控制消息具有一个 data
字段,其中包含消息数据的原生 (binary
) 值,并且如果此套接字库成功解码了数据,则可能还具有解码后的 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.
协议域,也称为地址族。
表示平台上名为 AF_*
(或 PF_*
)的协议域的小写 atom/0
。例如,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()}.
扩展错误信息。
一个包含附加(错误)信息的术语,如果已配置套接字 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 向量。关于 msg_send/0
的 iov
键,另请参阅 sendmsg/4
。根据 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
OS 协议级别,即:socket
或 protocol/0
名称。
socket
是 OS 头文件中的 SOL_SOCKET
协议级别,其选项名为 SO_
*。
-type linger() :: #{onoff := boolean(), linger := non_neg_integer()}.
C:struct linger
对应于用于管理 套接字选项 {socket, linger}
的 C struct 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
- 可选的对等地址,用于未连接的套接字。对应于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
- 可选的对等地址,用于未连接的套接字。对应于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
套接字选项。
用于 otp
伪协议级别的套接字选项,即:{otp, Name}
选项。
此协议级别是 Erlang/OTP 的套接字实现层,因此高于所有 OS 协议级别。
debug
-boolean/0
- 激活调试日志记录。iow
-boolean/0
- 通知统计计数器的环绕。controlling_process
-pid/0
- 套接字“所有者”。只有当前控制进程才能设置此选项。rcvbuf
-BufSize :: (default | integer()>0) | {N :: integer()>0, BufSize :: (default | integer()>0)}
- 接收缓冲区大小。值
default
仅对设置有效。N
指定在假定没有更多数据挂起之前,在紧密循环中执行的读取尝试次数。这是在调用 OS 协议栈的接收 API 时使用的接收缓冲区的分配大小,当没有请求特定大小(大小为 0)时。当接收函数返回时,接收缓冲区将重新分配为实际接收的大小。数据是否复制或就地缩小取决于分配器,并且可以在某种程度上在 Erlang VM 中进行配置。
类似的套接字选项
{socket,rcvbuf}
是操作系统协议栈的相关选项,在 Unix 上对应于SOL_SOCKET,SO_RCVBUF
。rcvctrlbuf
-BufSize :: (default | integer()>0)
- 调用操作系统协议栈的接收 API 时,用于辅助数据缓冲区的分配大小。值
default
仅对设置有效。sndctrlbuf
-BufSize :: (default | integer()>0)
- 调用操作系统协议栈的 sendmsg API 时,用于辅助数据缓冲区的分配大小。值
default
仅对设置有效。用户有责任设置足够大的缓冲区大小,以便容纳要发送的消息中编码的辅助数据。
请参阅 sendmsg 以及
msg_send/0
类型的ctrl
字段。fd
-integer/0
- 仅对 *get* 有效。操作系统协议层的套接字描述符。函数open/1,2
可用于根据此模块从现有的操作系统套接字描述符创建套接字。use_registry
-boolean/0
- 仅对 *get* 有效。该值在通过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_
*。
还有许多其他可能的协议,但上述协议是此套接字库实现套接字选项和/或控制消息的协议。
当 Erlang 虚拟机启动时,通过 C 库调用 getprotoent()
枚举操作系统已知的所有协议。请参阅操作系统的协议(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 结构字段名称中删除“_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 域套接字地址,又名本地地址 (AF_LOCAL
)。
当从此模块返回时,path
元素始终是 binary
。当提供给此模块中的 API 函数时,它可以是 string/0
,它将根据平台上的本机文件名编码编码为二进制。
在将地址路径提供给操作系统之前,将附加一个终止零字符,并且在将地址路径提供给调用者之前,将删除终止零字符。
如果地址的第一个字节为零,则 Linux 的不可移植抽象套接字地址扩展通过不在任一方向进行任何终止零处理来处理。
-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()}.
根据此模块的套接字。
由 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()
对于套接字唯一的、不透明的套接字句柄。
-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}.
套接字选项。
套接字选项的形式为 {Level, Opt}
,其中操作系统协议 Level
= level/0
,并且 Opt
是该协议层上的一个套接字选项。
选项的操作系统名称(除非另有说明)是 Opt
原子,采用大写形式,并根据 level/0
添加前缀。
注意
IPv6
选项pktoptions
是一种特殊(糟糕的)情况。它仅用于向后兼容性。请勿使用此选项。
注意
请参阅操作系统的文档,了解每个套接字选项。
下面具有 boolean/0
值类型的选项将把值 false
转换为 C int
,其值为 0
,并将值 true
转换为 !!0
(非(非假))。
值类型为 integer/0
的选项将被转换为 C 的 int
类型,其范围可能受限,例如字节:0..255
。请参阅操作系统文档。
调用 supports(options)
、supports(options, Level)
和 is_supported(options, {Level, Opt})
可以用来查找平台支持哪些套接字选项。
协议级别为 socket
的选项:
{socket, acceptconn}
-Value = boolean()
{socket, bindtodevice}
-Value = string()
{socket, broadcast}
-Value = boolean()
{socket, debug}
-Value = integer()
{socket, domain}
-Value =
domain/0
仅对获取有效。
套接字的协议域。例如在 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
仅对获取有效。
套接字的协议。例如在 Darwin 上不起作用。
{socket, rcvbuf}
-Value = integer()
{socket, rcvlowat}
-Value = integer()
{socket, rcvtimeo}
-Value =
timeval/0
默认情况下不支持此选项;必须使用
--enable-esock-rcvsndtimeo
配置选项显式构建 OTP 才能使用此选项。由于我们的实现使用非阻塞套接字,因此我们不清楚此选项是否有效,如何工作,甚至是否会导致故障。因此,我们不建议设置此选项。
请改用
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 才能使用此选项。由于我们的实现使用非阻塞套接字,因此我们不清楚此选项是否有效,如何工作,甚至是否会导致故障。因此,我们不建议设置此选项。
请改用
Timeout
参数,例如send/3
函数。{socket, timestamp}
-Value = boolean()
{socket, type}
-Value =
type/0
仅对获取有效。
套接字的类型。
协议级别为 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()
启用扩展的可靠错误消息传递。
警告! 启用此选项后,错误消息可能会到达套接字的错误队列中,应使用消息标志
errqueue
并使用recvmsg/1,2,3,4,5
读取,以在 消息的ctrl
字段中获取所有错误信息,作为 控制消息#{level := ip, type := recverr}
。一种可行的策略是首先使用
recvmsg/2,3,4
轮询错误队列,其中Timeout =:= 0
和Flags
包含errqueue
(忽略返回值{error, timeout}
),然后再读取实际数据,以确保清除错误队列。并使用nowait |
select_handle()
接收函数之一读取数据:recv/3,4
、recvfrom/3,4
或recvmsg/3,4,5
。否则,您可能会意外地在套接字的 '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 套接字。{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()
警告! 有关套接字的错误队列,请参阅套接字选项
{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}
-值 =
ipv6_hops/0
{ipv6, v6only}
-值 = boolean()
协议级别 sctp
的选项。另请参阅 RFC 6458。
{sctp, associnfo}
-值 =
sctp_assocparams/0
{sctp, autoclose}
-值 = integer()
{sctp, disable_fragments}
-值 = boolean()
{sctp, events}
-值 =
sctp_event_subscribe/0
仅对设置有效。
{sctp, initmsg}
-值 =
sctp_initmsg/0
{sctp, maxseg}
-值 = integer()
{sctp, nodelay}
-值 = boolean()
{sctp, rtoinfo}
-值 =
sctp_rtoinfo/0
协议级别 tcp
:的选项:
{tcp, congestion}
-值 = string()
{tcp, cork}
-值 = boolean()
{tcp, maxseg}
-值 = integer()
{tcp, nodelay}
-值 = boolean()
协议级别 udp
:的选项:
{udp, cork}
-值 = 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()}.
在监听套接字上接受连接。
ListenSocket
必须是面向连接的类型(类型 stream
或 seqpacket
,请参阅 open/1
),并设置为监听(请参阅 listen/1
)。
如果 Timeout
参数为 infinity
;则接受监听套接字的第一个待处理的传入连接,或者等待一个到达,并返回新的连接套接字。
如果 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().
将名称绑定到套接字。
创建套接字时(使用 open
),它没有分配地址。bind
分配由 Addr
参数指定的地址。
用于名称绑定的规则在域之间有所不同。
如果您将套接字绑定到例如 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}}
。
取消套接字监视器。
如果 MRef
是调用进程通过调用 monitor/1
获得的引用,则会删除此监视器。如果调用进程没有此类监视器(或者 MRef 不对应于监视器),则不会发生任何事情。
返回的值是以下之一
true
- 找到并删除了监视器。在这种情况下,没有传递与此监视器对应的'DOWN'
消息,也不会传递。false
- 未找到监视器,因此无法删除。这可能是因为监视器已触发,并且调用方消息队列中存在来自此监视器的'DOWN'
消息。
-spec close(Socket) -> ok | {error, Reason} when Socket :: socket(), Reason :: posix() | closed | timeout.
关闭套接字。
注意
请注意,对于
Protocol = tcp
(请参阅open/3
),尽管 TCP 保证当另一端看到流关闭时,我们在关闭之前发送的所有数据都已传递,但我们无法知道另一端是否获取了所有数据和流关闭。各种网络和操作系统问题都可能导致这种情况发生。为了获得这样的保证,我们需要在连接上实现带内确认协议,或者我们可以使用
shutdown
函数来表示将不再发送数据,然后等待另一端关闭套接字。然后我们会看到我们的读取端关闭套接字。通过这种方式,我们使用shutdown/2
实现了一个小型确认协议。另一端无法知道我们是否看到了套接字关闭,但在客户端/服务器场景中,这通常是不相关的。
-spec connect(Socket :: socket()) -> ok | {error, Reason} when Reason :: posix() | closed | invalid().
完成 connect/3
操作。
请参阅此模块参考手册页面开头的异步调用说明。
在 select
系统上,此函数在收到 select
消息 {'$socket',
Socket
, select,
SelectHandle
}
后,最终完成套接字上的连接设置,并返回连接设置是否成功。
为了向后兼容,允许再次调用 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()}.
将套接字连接到给定地址。
此函数将套接字连接到 SockAddr
参数指定的地址。
如果连接尝试已经在进行中(由另一个进程),则返回 {error, already}
。
注意
在 Windows 上,套接字必须是 绑定的。
如果超时参数(参数 3)为 infinity
,则由操作系统实现来决定连接尝试何时失败,然后返回什么;可能是 {error, etimedout}
。操作系统超时可能非常长。
如果超时参数(参数 3)是超时值(non_neg_integer/0
);如果在 Timeout
毫秒内未建立连接,则返回 {error, timeout}
。
注意
请注意,当此调用返回
{error, timeout}
时,套接字的连接状态是不确定的,因为平台的网络堆栈可能在任何时间(最长为某个平台特定的超时)完成连接。重复尝试连接到同一地址是可以的,但连接到不同的地址可能会导致连接到任一地址。
安全的方法是关闭套接字并重新开始。
另请注意,这适用于取消下面描述的
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}.
获取套接字选项的值。
获取操作系统协议级别的套接字选项的值,或者从 otp
伪协议级别获取,这是此模块在操作系统协议级别之上的实现级别。
有关 otp
协议级别的描述,请参阅类型 otp_socket_option() 。
有关此实现所知的操作系统协议级别选项,它们如何与操作系统选项名称相关联,以及它们是否有任何已知的特性,请参阅类型 socket_option/0
。
哪些选项有效取决于操作系统以及套接字的类型(domain/0
、type/0
和 protocol/0
)。有关更多信息,请参阅类型 t:socket_option()
和用户指南中的套接字选项章节。
注意
并非所有选项在所有平台上都有效,或者可以获取。也就是说,即使此
socket
实现支持某个选项;也并不意味着底层操作系统支持该选项。
获取套接字选项(向后兼容函数)。
等效于 getopt(Socket, {Level, Opt})
,或者在特殊情况下,如果 Opt = {NativeOpt ::
integer/0
, ValueSpec}
,则等效于 getopt_native(Socket, {Level, NativeOpt}, ValueSpec)
。
请改用 getopt/2
或 getopt_native/3
来将选项级别和名称作为单个术语处理,并明确区分已知选项和本机选项。
-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_option()
元组指定套接字选项,其中包含已知的 Level = level()
和整数 NativeOpt
,或者同时包含整数 NativeLevel
和 NativeOpt
。
如何解码选项值必须通过 ValueType
指定,或者通过指定 ValueSize
来获取将包含获取的选项值的 binary/0
,或者通过指定一个 binary/0
ValueSpec
,该 ValueSpec
将被复制到一个缓冲区,供 getsockopt()
调用在其中写入该值,该值将作为新的 binary/0
返回。
如果 ValueType
是 integer
,则会获取一个 C
类型 (int)
,如果它是 boolean
,则会获取一个 C
类型 (int)
,并根据 C
实现关于 true 和 false 的概念将其转换为 boolean/0
。
选项是否有效取决于平台以及它是哪种类型的套接字(domain/0
、 type/0
和 protocol/0
)。
NativeLevel
和 NativeOpt
的整数值以及 Value
编码必须从正在运行的系统的头文件中推导出来。
-spec i() -> ok.
以表格格式将所有套接字的信息打印到 erlang shell。
每个套接字打印的信息由默认的 info_keys/0
集合(所有键)指定。
打印的套接字是由此 socket
模块的实现创建的所有套接字。
-spec i(InfoKeys :: info_keys()) -> ok; (Domain :: inet | inet6 | local) -> ok; (Proto :: sctp | tcp | udp) -> ok; (Type :: dgram | seqpacket | stream) -> ok.
以表格格式将所有套接字的信息打印到 erlang shell。
如果参数是 info_keys/0
的列表,则打印所有套接字的指定信息。请参阅 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().
以表格格式将选定套接字的信息打印到 erlang shell。
参数 InfoKeys
指定每个套接字打印哪些信息。
如果第一个参数是 Domain
,则打印该特定 domain/0
的所有套接字的信息。
如果第一个参数是 Proto
,则打印该特定 protocol/0
的所有套接字的信息。
如果第一个参数是 Type
,则打印该特定 type/0
的所有套接字的信息。
-spec info() -> info().
获取有关此 socket
库的杂项信息。
该函数返回一个映射,其中每个信息项作为键值对。
注意
为了确保数据完整性,会在需要时获取互斥锁。因此,请勿频繁调用此函数。
-spec info(Socket) -> socket_info() when Socket :: socket().
获取有关套接字的杂项信息。
该函数返回一个映射,其中每个信息项作为键值对,反映了套接字的“当前”状态。
注意
为了确保数据完整性,会在需要时获取互斥锁。因此,请勿频繁调用此函数。
-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.
设置套接字(设备)参数。
此函数根据 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
- 获取已连接套接字的各种 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.
获取或设置套接字(设备)参数。
此函数根据以下 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
- 启用(或禁用)套接字接收通过网络接口的所有 IPv4 或 IPv6 数据包。Socket
必须是以下之一:该套接字还必须绑定到(显式的)本地 IPv4 或 IPv6 接口(不允许使用
any
)。设置此 IOCTL 需要提升的权限。
使用以下 SetRequest
参数,此函数设置请求参数的 Value
(自 OTP 26.1 起)。
rcvall_igmpmcall
- 启用(或禁用)套接字接收 IGMP 组播 IP 流量,而不接收任何其他 IP 流量。该套接字必须使用地址 域
inet
,套接字 类型raw
和 协议igmp
创建。该套接字还必须绑定到(显式的)本地接口(不允许使用
any
)。接收缓冲区必须足够大。
设置此 IOCTL 需要提升的权限。
rcvall_mcall
- 启用(或禁用)套接字接收所有组播 IP 流量(例如,所有目标 IP 地址在 224.0.0.0 到 239.255.255.255 范围内的 IP 数据包)。该套接字必须使用地址 域
inet
,套接字 类型raw
和 协议udp
创建。该套接字还必须绑定到(显式的)本地接口(不允许使用
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.
设置套接字(设备)参数。
此函数根据 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
。
检查是否支持某个套接字功能。
如果 supports/0
在其返回的列表中有一个 {Key1, true}
元组或一个 {Key1, list()}
元组,则返回 true
,否则返回 false
(对于未知键也是如此)。
示例
true = socket:is_supported(local),
检查是否支持某个套接字功能。
如果 supports(Key1)
在其返回的列表中有一个 {Key2, true}
元组,则返回 true
,否则返回 false
(对于未知键也是如此)。
示例
true = socket:is_supported(msg_flags, errqueue),
使套接字监听连接。
等效于 listen(Socket, Backlog)
,其中 Backlog
的默认值为(当前为 5
)。
使套接字监听连接。
Backlog
参数表示传入但尚未接受的连接的队列长度。该数字的具体解释取决于操作系统的协议栈,但生成的有效队列长度很可能被视为至少那么长。
注意
在 Windows 上,套接字必须是已绑定的。
启动套接字监视器。
如果 Socket
不存在,或者稍后触发监视器,则会向调用 monitor/1
的进程发送一个 'DOWN'
消息,其模式如下:
{'DOWN', MonitorRef, socket, Socket, Info}
Info
是套接字的终止原因,如果 Socket
在启动监视器时不存在,则为 nosock
。
多次调用同一 Socket
的 socket:monitor/1
不是错误;每次调用都会创建一个独立的监视器实例。
-spec number_of() -> non_neg_integer().
返回活动套接字的数量。
等效于 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.
创建套接字。
带有参数 Domain
和 Type
等效于 open(Domain, Type, default, #{})
。
带有参数 FD
和 Opts
(自 OTP 23.0 起)
基于必须是套接字的现有文件描述符创建一个用于通信的端点(套接字)。此函数尝试从系统中检索文件描述符的 domain
、type
和 protocol
。但是,这并非在所有平台上都可行;在这种情况下,应在 Opts
中指定它们。
Opts
参数可以提供额外的信息:
domain
- 文件描述符的通信域。另请参阅type
- 文件描述符的套接字类型。另请参阅
open/2,3,4
。protocol
- 文件描述符的协议。原子default
等效于整数协议号0
,这意味着给定域和类型的默认协议。如果无法从平台的套接字检索协议,并且未指定
protocol
,则将使用默认协议,该协议可能正确,也可能不正确。另请参阅
open/2,3,4
。dup
- 如果false
,则不要复制提供的文件描述符。默认为
true
;复制文件描述符。debug
- 如果true
,则启用套接字调试日志记录。默认为
false
;不启用套接字调试日志记录。use_registry
- 启用或禁用此套接字使用套接字注册表。这将覆盖全局设置。默认为全局设置,请参阅
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.
创建套接字。
使用参数 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.
创建套接字。
创建一个用于通信的端点(套接字)。
Domain
和 Type
可以是 integer/0
,如平台头文件中定义。 Protocol
也一样,如平台 services(5)
数据库中定义。 另请参阅操作系统手册页中关于库调用 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()
- 启用或禁用此套接字的套接字注册表的使用。这将覆盖全局值。默认为全局值,请参见
use_registry/1
。
-spec peername(Socket :: socket()) -> {ok, SockAddr} | {error, Reason} when SockAddr :: sockaddr_recv(), Reason :: posix() | closed.
返回套接字的远程地址。
返回已连接的对等方的地址,即套接字的远程端。
-spec recv(Socket :: socket(), Flags :: list()) -> dynamic(); (Socket :: socket(), Length :: non_neg_integer()) -> dynamic().
在连接的套接字上接收数据。
使用参数 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().
在连接的套接字上接收数据。
使用参数 Length
和 Flags
;等效于 recv(Socket, Length, Flags, infinity)
。
使用参数 Length
和 TimeoutOrHandle
;等效于 recv(Socket, Length, [], TimeoutOrHandle)
。自 OTP 22.1 起,允许使用 TimeoutOrHandle :: nowait
。自 OTP 24.0 起,允许使用 TimeoutOrHandle :: Handle
。
使用参数 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().
在连接的套接字上接收数据。
参数 Length
指定要接收的字节数,特殊情况 0
表示“所有可用的”。
当 Length
为 0
时,将使用默认缓冲区大小,该大小可以通过 socket:setopt(Socket, {otp,recvbuf}, BufSz)
设置。
消息 Flags
可以是符号 msg_flag/0
和/或 integer/0
,如平台相应头文件中定义。所有符号标志和整数的值都进行或运算。
当出现套接字错误时,此函数返回 {error, Reason}
,或者如果在错误之前收到一些数据,则返回 {error, {Reason, Data}}
(仅当套接字类型为 stream
时才会发生)。
如果 Timeout
参数为 infinity
,则等待数据到达。对于类型为 stream
的套接字,此调用将不会返回,直到可以交付所有请求的数据,或者如果请求了“所有可用的”,则在第一块数据到达时,或者如果操作系统报告此操作出现错误时返回。
如果 Timeout
参数是超时值 (non_neg_integer/0
),如果在 Timeout
毫秒后没有数据到达,则返回 {error, timeout}
,或者如果在类型为 stream
的套接字上收到了一些但不是足够的数据,则返回 {error, {timeout, Data}}
。
Timeout = 0
仅轮询操作系统接收调用,而不启用异步调用机制。如果无法立即获得任何数据,则返回 {error, timeout}
。在类型为 stream
的套接字上,如果有少量数据但无法立即获得足够的数据,则返回 {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
的套接字,如果 Length > 0
并且没有足够的可用数据,则此函数将返回 {select, {SelectInfo, Data}}
,其中包含部分 Data
。重复调用以完成操作可能需要更新的 Length
参数。
-spec recvfrom(Socket :: socket(), Flags :: list()) -> dynamic(); (Socket :: socket(), BufSz :: non_neg_integer()) -> dynamic().
在套接字上接收消息。
使用参数 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().
在套接字上接收消息。
使用参数 BufSz
和 Flags
;等效于 recvfrom(Socket, BufSz, Flags, infinity)
。
使用参数 BufSz
和 TimeoutOrHandle
;等效于 recv(Socket, BufSz, [], TimeoutOrHandle)
。
使用参数 Flags
和 TimeoutOrHandle
;等效于 recv(Socket, 0, Flags, TimeoutOrHandle)
自 OTP 22.1 起,允许使用 TimeoutOrHandle :: 'nowait'
。
自 OTP 24.0 起,允许使用 TimeoutOrHandle :: Handle
。
-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().
在套接字上接收消息。
此函数适用于非面向连接的套接字,例如类型为 dgram
或 seqpacket
的套接字,这些套接字可能收到来自不同源地址的消息。
参数 BufSz
指定接收缓冲区的字节数。如果缓冲区大小太小,则消息将被截断。
如果 BufSz
为 0
,则使用默认缓冲区大小,可以通过 socket:setopt(Socket, {otp,recvbuf}, BufSz)
设置。
如果没有已知合适的缓冲区大小,则可以使用接收消息标志 peek
。当使用此标志时,消息不会从底层缓冲区中“消耗”,因此需要另一个 recvfrom/1,2,3,4
调用,可能需要调整缓冲区大小。
消息 Flags
可以是符号 msg_flag/0
和/或 integer/0
,如平台相应头文件中定义。所有符号标志和整数的值都进行或运算。
如果 Timeout
参数为 infinity
,则等待消息到达或套接字错误。
如果 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().
在套接字上接收消息。
使用参数 Flags
;等效于 recvmsg(Socket, 0, 0, Flags, infinity)
。
使用参数 TimeoutOrHandle
;等效于 recvmsg(Socket, 0, 0, [], TimeoutOrHandle)
。
自 OTP 22.1 起,允许使用 TimeoutOrHandle :: nowait
。
自 OTP 24.0 起,允许使用 TimeoutOrHandle :: Handle
。
-spec recvmsg(Socket :: dynamic(), Flags :: list(), TimeoutOrHandle :: dynamic()) -> dynamic(); (Socket :: dynamic(), BufSz :: integer(), CtrlSz :: integer()) -> dynamic().
在套接字上接收消息。
使用参数 Flags
;等效于 recvmsg(Socket, 0, 0, Flags, infinity)
。
使用参数 TimeoutOrHandle
;等效于 recvmsg(Socket, 0, 0, [], TimeoutOrHandle)
。
自 OTP 22.1 起,允许使用 TimeoutOrHandle :: nowait
。
自 OTP 24.0 起,允许使用 TimeoutOrHandle :: Handle
。
-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().
在套接字上接收消息。
此函数接收数据和控制消息。
参数 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
,如平台相应头文件中定义。所有符号标志和整数的值都进行或运算。
如果 Timeout
参数为 infinity
,则等待消息到达或发生套接字错误。
如果 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()) -> _.
在连接的套接字上发送数据。
使用参数 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().
在连接的套接字上发送数据。
消息 Flags
可以是符号 msg_flag/0
和/或 integer/0
,如平台相应头文件中定义。所有符号标志和整数的值都进行或运算。
如果 Data
不是 binary/0
,则在调用平台网络 API 之前,会将其复制到一个 binary/0
中,因为需要单个缓冲区。返回的 RestData
是它的一个子二进制。
返回值指示平台网络层的结果
ok
- 所有数据都被操作系统接受以进行传递{ok, RestData}
- 部分(但不是全部)数据被接受,但没有报告错误(部分成功发送)。RestData
是未被接受的Data
的尾部。对于 类型为
stream
的套接字,这种情况不会发生,因为会重试此类部分成功发送,直到数据被接受进行传递或发生错误。对于 类型为
dgram
的套接字,这种情况可能也不应该发生,因为无法原子传递的消息应该会产生错误。尽管如此,平台网络层仍然有可能返回此值,对于 类型为
seqpacket
的套接字,这种情况肯定更可能发生。{error, Reason}
- 已报告错误,并且没有数据被接受进行传递。Reason :: posix/0
是平台网络层报告的内容。closed
表示此套接字库已获知套接字已关闭,而invalid/0
表示此套接字库发现参数无效。{error, {Reason, RestData}}
- 已报告错误,但在此之前,部分数据已被接受进行传递。RestData
是未被接受的Data
的尾部。请参见上面的{error, Reason}
。这仅当 类型为
stream
的套接字发生部分成功发送并重试直到发生错误时才会发生。
如果 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().
在套接字上发送文件。
等效于 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().
在套接字上发送文件。
等效于 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().
在套接字上发送文件。
等效于 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().
在套接字上发送文件。
注意
此函数在 Windows 上不受支持。
FileHandle
参数必须引用 file:open/2
中所述的打开的原始文件。
Offset
参数是从中开始读取的文件偏移量。默认偏移量为 0
。
Count
参数是要从 FileHandle
传输到 Socket
的字节数。如果 Count = 0
(默认值),则传输将在文件末尾停止。
返回值指示平台网络层的结果
{ok, BytesSent}
- 传输在BytesSent
字节的数据后成功完成。{error, Reason}
- 已报告错误,并且没有传输任何数据。Reason :: posix/0
是平台网络层报告的内容。closed
表示此套接字库已获知套接字已关闭,而invalid/0
表示此套接字库发现参数无效。{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
消息后,调用 sendfile/2,3,4,5
,其中 SelectInfo
作为 Continuation
参数,以完成操作。
如果函数调用时带有 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().
在套接字上发送数据和控制消息。
使用参数 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().
在套接字上发送数据和控制消息。
参数 Msg
是一个映射,其中包含要发送的数据,数据位于键 iov
下,并表示为 erlang:iovec/0
(binary/0
列表)。它还可能包含目标地址,该地址位于键 addr
下,如果套接字未连接,则该地址是必需的。如果套接字已连接,最好不要包含 addr
键,因为平台可能会将其视为错误(或忽略它)。在键 ctrl
下,可能存在一个协议和平台相关的控制消息(也称为辅助数据或控制信息)列表,用于发送。
消息数据作为 I/O 向量提供给平台的网络层,而无需复制内容。如果 I/O 向量中的元素数量大于平台允许的数量(在 info/0
中的 iov_max
字段中报告),则对于 类型为 stream
的套接字,发送将迭代所有元素,但对于其他套接字类型,调用将失败。
有关 Flags
参数和返回值的说明,请参见 send/4
。
注意
在 Windows 上,此函数只能与数据报和原始套接字一起使用。
如果 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
消息后,调用 sendmsg/3,4
并将 SelectInfo
作为 Cont
参数,以完成操作。
使用参数 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().
在套接字上发送数据。
使用参数 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().
在套接字上发送数据。
使用参数 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 起)
有关 TimeoutOrHandle
的说明,请参见 sendto/5
的最后一个参数(参数 5)。
-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().
在套接字上发送数据。
To
参数是要发送数据的目标地址。对于已连接的套接字,此参数仍会传递给操作系统调用,该调用可能会忽略地址或返回错误。
有关 Flags
和 Data
参数以及返回值的说明,请参见 send/4
。
如果 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
消息后,调用 sendto/3,4
并将 SelectInfo
作为 Cont
参数,以完成操作。
-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().
在连接的套接字上发送 erlang:iovec/0
数据。
有关如何处理向平台网络层传递 IOV
数据,请参阅 sendmsg/4
。
返回值指示平台网络层的结果
ok
- 所有数据都已被操作系统接受以进行传递。{ok, RestIOV}
- 部分但并非所有数据都被接受,但未报告错误(部分成功发送)。RestIOV
是未被接受的IOV
的尾部。{error, Reason}
- 已报告错误,并且没有数据被接受以进行传递。Reason :: posix/0
是平台网络层报告的内容。closed
表示此套接字库被告知套接字已关闭,invalid/0
表示此套接字库发现参数无效。{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().
在连接的套接字上发送数据,续传。
继续在已连接的套接字上发送数据。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().
设置套接字选项。
设置操作系统协议级选项或 otp
伪协议级选项。后者是此模块在操作系统协议级别之上的实现级别。
有关 otp
协议级别的描述,请参阅类型 otp_socket_option() 。
有关此实现所知的操作系统协议级别选项,它们如何与操作系统选项名称相关联,以及它们是否有任何已知的特性,请参阅类型 socket_option/0
。
哪些选项有效取决于操作系统以及套接字的类型(domain/0
、type/0
和 protocol/0
)。有关更多信息,请参阅类型 t:socket_option()
和用户指南中的套接字选项章节。
注意
并非所有选项在所有平台上都有效或可以设置。也就是说,即使此
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().
设置“原生”套接字选项。
设置我们的实现可能未知的套接字选项,或类型与我们的实现不兼容(即“本机模式”)的套接字选项。
如果 Value
是一个 integer/0
,它将用作 C
类型 (int)
;如果它是一个 boolean/0
,它将用作 C
类型 (int)
,其中包含 C
实现的 false
或 true
值;如果它是一个 binary/0
,则将其内容和大小用作选项值。
套接字选项可以使用普通的 socket_option/0
元组指定,也可以使用符号 Level
,格式为 {
Level :: level/0
,
NativeOpt :: integer/0
}
,或者为 NativeLevel
和 NativeOpt
都使用整数,格式为 {
NativeLevel :: integer/0
,
NativeOpt :: integer/0
}
。
选项是否有效取决于平台以及它是哪种类型的套接字(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.
获取套接字的地址。
返回套接字当前绑定的地址。如果绑定地址使用了通配符端口 0
,则此函数返回的地址包含操作系统选择的临时端口。
-spec supports() -> [{Key1 :: term(), boolean() | [{Key2 :: term(), boolean() | [{Key3 :: term(), boolean()}]}]}].
检索有关模块和平台支持的套接字功能的信息。
返回一个列表,其中包含 {Key1,
supports(Key1)
}
元组,对应于 supports/1
中描述的每个 Key1
,以及以下每个键的 {Key, boolean()}
元组,顺序不限
sctp
- SCTP 支持ipv6
- IPv6 支持local
- Unix 域套接字支持 (AF_UNIX | AF_LOCAL
)netns
- 网络命名空间支持(Linux,setns(2)
)sendfile
- Sendfile 支持 (sendfile(2)
)
检索有关模块和平台支持的套接字功能的信息。
如果 Key1 = msg_flags
,则返回一个 {Flag, boolean()}
元组的列表,对应于 msg_flag/0
中的每个 Flag
,其中 boolean/0
表示此平台上是否支持该标志。
如果 Key1 = protocols
,则返回一个 {Name, boolean()}
元组的列表,对应于protocol/0
中的每个 Name
,其中 boolean/0
表示此平台上是否支持该协议。
如果 Key1 = options
,则返回一个 {SocketOption, boolean()}
元组的列表,对应于 socket_option/0
中的每个 SocketOption
,其中 boolean/0
表示此平台上是否支持该套接字选项。
任何返回的列表都没有特定的顺序。
对于 Key1
的其他值,返回 []
。请注意,在此模块的未来版本或在不同的平台上,可能支持更多的键。
检索有关模块和平台支持的套接字功能的信息。
如果 Key1 = options
,对于 level/0
中的 Key2
,返回一个 {Opt, boolean()}
元组的列表,对应于在该 Level = Key2
上所有已知的套接字选项 Opt
,其中 boolean/0
表示此平台上是否支持该套接字选项。请参阅 setopt/3
和 getopt/2
。
任何返回的列表都没有特定的顺序。
对于 Key1
或 Key2
的其他值,返回 []
。请注意,在此模块的未来版本或在不同的平台上,可能支持更多的键。
-spec use_registry(D :: boolean()) -> ok.
设置全局 use_registry
选项默认值。
全局更改是否使用套接字注册表。请注意,在创建单个套接字时仍然可以显式覆盖此设置,请参阅 open/2,3,4
了解更多信息(Opts :: map/0
)。
-spec which_sockets() -> [socket()].
返回所有已知套接字的列表。
-spec which_sockets(FilterRule) -> [socket()] when FilterRule :: inet | inet6 | local | stream | dgram | seqpacket | sctp | tcp | udp | pid() | fun((socket_info()) -> boolean()).
返回已知套接字的过滤列表。
有几个预定义的 FilterRule
和一个通用的规则。
inet | inet6
- 仅返回具有匹配domain/0
的套接字。stream | dgram | seqpacket
- 仅返回具有匹配type/0
的套接字。sctp | tcp | udp
- 仅返回具有匹配protocol/0
的套接字。pid/0
- 仅返回具有匹配控制进程的套接字。请参阅 OTP 套接字选项controlling_process
。fun((socket_info()) -> boolean())
- 通用过滤规则。一个接受套接字信息并返回boolean/0
的函数,指示是否应返回该套接字。