查看源代码 gen_sctp (内核 v10.2)

SCTP 套接字接口。

此模块提供通过 SCTP 套接字进行通信的功能。该实现假设操作系统内核通过用户级 套接字 API 扩展支持 SCTP (RFC 2960)

在开发过程中,此实现在以下系统上进行了测试:

  • Linux Fedora Core 5.0(需要内核 2.6.15-2054 或更高版本)
  • Solaris 10, 11

在 OTP 适配期间,在以下系统上进行了测试:

  • SUSE Linux Enterprise Server 10 (x86_64) 内核 2.6.16.27-0.6-smp,使用 lksctp-tools-1.0.6
  • Solaris 10 上的简要测试
  • SUSE Linux Enterprise Server 10 Service Pack 1 (x86_64) 内核 2.6.16.54-0.2.3-smp,使用 lksctp-tools-1.0.7
  • FreeBSD 8.2

此模块是为一对多样式套接字(类型 seqpacket)编写的。通过添加 peeloff/2,引入了一对一样式套接字(类型 stream)。

可以使用以下命令找到此模块的记录定义:

-include_lib("kernel/include/inet_sctp.hrl").

这些记录定义使用“新”的拼写“adaptation”,而不是已弃用的“adaption”,无论底层 C API 使用哪个拼写。

SCTP 套接字选项

允许的 SCTP 套接字选项集在构造上与 TCP、UDP 和通用 inet 选项集正交。此处仅列出 SCTP 套接字允许的选项。

选项可以在调用 open/1,2 时在套接字上设置,并在调用 connect/4,5 或通过调用 inet:setopts/2 时更改。可以使用 inet:getopts/2 检索它们。

  • {mode, list|binary} | list | binary - 确定从 recv/1,2 返回的数据类型或主动模式数据消息中的数据类型。

  • {active, false|true|once|N}

    • 如果 false被动模式,默认值),则调用者必须执行显式的 recv 调用才能从套接字检索可用数据。

    • 如果 true|once|N主动模式),则接收到的数据或事件将发送到所有者进程。有关消息格式,请参阅 open/0..2

    • 如果 true(完全主动模式),则没有流量控制。

      注意

      请注意,这可能会导致消息队列溢出,例如导致虚拟机内存耗尽并崩溃。

    • 如果 once,则只有一个消息会自动放入消息队列,并且模式重置为被动。这提供了流量控制,并使接收器可以侦听与其他进程间消息交错的传入 SCTP 数据。

    • 如果 active 指定为 -32768 到 32767(包括)范围内的整数 N,则该数字将添加到套接字的数据消息计数器。如果加法的结果为负数,则计数器设置为 0。一旦计数器达到 0,无论是通过传递消息还是通过使用 inet:setopts/2 显式设置,套接字模式都会重置为被动({active, false})。当 {active, N} 模式下的套接字转换为被动模式时,消息 {sctp_passive, Socket} 将发送到控制进程,以通知它,如果要从套接字接收更多数据消息,则必须调用 inet:setopts/2 将套接字设置回主动模式。

  • {tos, integer()} - 将发送的 IP 数据报的服务类型字段设置为指定值。这有效地确定了出站数据包的优先级策略。可接受的值取决于系统。

  • {priority, integer()} - 上面 tos 的协议无关的等效项。设置优先级意味着也设置 tos

  • {dontroute, true|false} - 默认为 false。如果 true,则内核不会通过任何网关发送数据包,而只会将数据包发送到直接连接的主机。

  • {reuseaddr, true|false} - 默认为 false。如果 true,则可以立即重用套接字的本地绑定地址 {IP,Port}。不会执行 CLOSE_WAIT 状态的等待(某些类型的服务器可能需要)。

  • {sndbuf, integer()} - 此套接字的操作系统内核发送缓冲区的大小(以字节为单位)。对于大于 val(sndbuf) 的数据报,将发生发送错误。设置此选项还会调整驱动程序缓冲区的大小(请参见上面的 buffer)。

  • {recbuf, integer()} - 此套接字的操作系统内核接收缓冲区的大小(以字节为单位)。对于大于 val(recbuf) 的数据报,将发生发送错误。设置此选项还会调整驱动程序缓冲区的大小(请参见上面的 buffer)。

  • {non_block_send, boolean()} - 如果此选项已设置为 true,则原本会阻塞(挂起)的发送调用将立即返回,并显示例如 {error, eagain}。默认为 false

  • {sctp_module, module()} - 覆盖使用的回调模块。IPv4 的默认为 inet_sctp,IPv6 的默认为 inet6_sctp

  • {sctp_rtoinfo, #sctp_rtoinfo{}}

    #sctp_rtoinfo{
          assoc_id = assoc_id(),
          initial  = integer(),
          max      = integer(),
          min      = integer()
    }

    确定由 assoc_id 指定的关联的重传超时参数(以毫秒为单位)。

    assoc_id = 0(默认)指示整个端点。有关字段值的确切语义,请参见 RFC 2960SCTP 套接字 API 扩展

  • {sctp_associnfo, #sctp_assocparams{}}

    #sctp_assocparams{
          assoc_id                 = assoc_id(),
          asocmaxrxt               = integer(),
          number_peer_destinations = integer(),
          peer_rwnd                = integer(),
          local_rwnd               = integer(),
          cookie_life              = integer()
    }

    确定由 assoc_id 指定的关联的关联参数。

    assoc_id = 0(默认)指示整个端点。有关其语义的讨论,请参见 SCTP 套接字 API 扩展。很少使用。

  • {sctp_initmsg, #sctp_initmsg{}}

    #sctp_initmsg{
         num_ostreams   = integer(),
         max_instreams  = integer(),
         max_attempts   = integer(),
         max_init_timeo = integer()
    }

    确定此套接字在与其对等方建立关联时尝试协商的默认参数。必须在 open/* 之后但在第一次 connect/* 之前设置。#sctp_initmsg{} 也可以用作对新对等方的第一次 send/* 调用(创建新关联时)的辅助数据。

    • num_ostreams - 出站流的数量

    • max_instreams - 入站流的最大数量

    • max_attempts - 建立关联时的最大重传次数

    • max_init_timeo - 建立关联的超时时间(以毫秒为单位)

  • {sctp_autoclose, integer() >= 0} - 确定空闲关联自动关闭的时间(以秒为单位)。0 表示关联永远不会自动关闭。

  • {sctp_nodelay, true|false} - 启用|禁用 Nagle 算法,用于将小数据包合并为较大的数据包。这会以延迟为代价来提高吞吐量。

  • {sctp_disable_fragments, true|false} - 如果 true,则在尝试发送大于当前 PMTU 大小的消息(这将需要分片/重组)时会引发错误。请注意,消息分片不会影响其传递的逻辑原子性;提供此选项仅出于性能原因。

  • {sctp_i_want_mapped_v4_addr, true|false} - 启用|禁用将 IPv4 地址自动映射到 IPv6 地址(如果套接字地址族为 AF_INET6)。

  • {sctp_maxseg, integer()} - 确定使用消息分片时的最大块大小。如果 0,则块大小仅受路径 MTU 的限制。

  • {sctp_primary_addr, #sctp_prim{}}

    #sctp_prim{
          assoc_id = assoc_id(),
          addr     = {IP, Port}
    }
     IP = ip_address()
     Port = port_number()

    对于由 assoc_id 指定的关联,{IP,Port} 必须是对等地址之一。此选项确定指定的地址被本地 SCTP 堆栈视为对等方的主地址。

  • {sctp_set_peer_primary_addr, #sctp_setpeerprim{}}

    #sctp_setpeerprim{
          assoc_id = assoc_id(),
          addr     = {IP, Port}
    }
     IP = ip_address()
     Port = port_number()

    设置后,通知对等方使用 {IP, Port} 作为由 assoc_id 指定的关联的本地端点的主地址。

  • {sctp_adaptation_layer, #sctp_setadaptation{}}

    #sctp_setadaptation{
          adaptation_ind = integer()
    }

    设置后,请求本地端点使用由 adaptation_ind 指定的值作为建立新关联的适应指示参数。有关详细信息,请参见 RFC 2960SCTP 套接字 API 扩展

  • {sctp_peer_addr_params, #sctp_paddrparams{}}

    #sctp_paddrparams{
          assoc_id   = assoc_id(),
          address    = {IP, Port},
          hbinterval = integer(),
          pathmaxrxt = integer(),
          pathmtu    = integer(),
          sackdelay  = integer(),
          flags      = list()
    }
    IP = ip_address()
    Port = port_number()

    确定由 assoc_id 和对等地址 address 指定的关联的各种每个地址参数(SCTP 协议支持多宿主,因此多个地址可以对应于指定的关联)。

    • hbinterval - 心跳间隔,以毫秒为单位

    • pathmaxrxt - 在此地址被认为无法访问(并选择备用地址)之前的最大重传次数

    • pathmtu - 固定路径 MTU,如果禁用自动发现(请参见下面的 flags

    • sackdelay - SAC 消息的延迟(以毫秒为单位)(如果启用延迟,请参见下面的 flags

    • flags - 提供以下标志

      • hb_enable - 启用心跳

      • hb_disable - 禁用心跳

      • hb_demand - 立即启动心跳

      • pmtud_enable - 启用自动路径 MTU 发现

      • pmtud_disable - 禁用自动路径 MTU 发现

      • sackdelay_enable - 启用 SAC 延迟

      • sackdelay_disable - 禁用 SAC 延迟

  • {sctp_default_send_param, #sctp_sndrcvinfo{}}

    #sctp_sndrcvinfo{
          stream     = integer(),
          ssn        = integer(),
          flags      = list(),
          ppid       = integer(),
          context    = integer(),
          timetolive = integer(),
          tsn        = integer(),
          cumtsn     = integer(),
          assoc_id   = assoc_id()
    }

    #sctp_sndrcvinfo{} 既用于此套接字选项,也用作发送或接收 SCTP 消息时的辅助数据。当设置为选项时,它为后续在由 assoc_id 指定的关联上进行的 send 调用提供默认值。

    assoc_id = 0(默认)表示整个端点。

    以下字段通常必须由发送方指定

    • sinfo_stream - 在关联中用于发送消息的流编号(从 0 开始);

    • sinfo_flags - 可识别以下标志

      • unordered - 消息将以无序方式发送

      • addr_over - send 中指定的地址将覆盖主对等地址

      • abort - 中止当前关联,而不刷新任何未发送的数据

      • eof - 正常关闭当前关联,并刷新未发送的数据

      其他字段很少使用。有关完整信息,请参阅 RFC 2960SCTP 的套接字 API 扩展

  • {sctp_events, #sctp_event_subscribe{}}

    #sctp_event_subscribe{
            data_io_event          = true | false,
            association_event      = true | false,
            address_event          = true | false,
            send_failure_event     = true | false,
            peer_error_event       = true | false,
            shutdown_event         = true | false,
            partial_delivery_event = true | false,
            adaptation_layer_event = true | false
    }

    此选项确定要接收的 SCTP 事件(通过 recv/*)以及数据。唯一的例外是 data_io_event,它启用或禁用接收 #sctp_sndrcvinfo{} 辅助数据,而不是事件。默认情况下,除了 adaptation_layer_event 之外的所有标志都启用,尽管驱动程序本身使用 sctp_data_io_eventassociation_event,并且不将其导出到用户级别。

  • {sctp_delayed_ack_time, #sctp_assoc_value{}}

    #sctp_assoc_value{
          assoc_id    = assoc_id(),
          assoc_value = integer()
    }

    很少使用。确定指定关联或整个端点的 ACK 时间(由 assoc_value 指定,以毫秒为单位),如果 assoc_value = 0(默认)。

  • {sctp_status, #sctp_status{}}

    #sctp_status{
          assoc_id            = assoc_id(),
          state               = atom(),
          rwnd                = integer(),
          unackdata           = integer(),
          penddata            = integer(),
          instrms             = integer(),
          outstrms            = integer(),
          fragmentation_point = integer(),
          primary             = #sctp_paddrinfo{}
    }

    此选项为只读。它确定由 assoc_id 指定的 SCTP 关联的状态。以下是 state 的可能值(状态名称大多是不言自明的)

    • sctp_state_empty - 默认。表示没有其他状态处于活动状态。

    • sctp_state_closed

    • sctp_state_cookie_wait

    • sctp_state_cookie_echoed

    • sctp_state_established

    • sctp_state_shutdown_pending

    • sctp_state_shutdown_sent

    • sctp_state_shutdown_received

    • sctp_state_shutdown_ack_sent

    其他字段的语义

    • sstat_rwnd - 关联的当前接收窗口大小

    • sstat_unackdata - 未确认的数据块数

    • sstat_penddata - 待接收的数据块数

    • sstat_instrms - 入站流的数量

    • sstat_outstrms - 出站流的数量

    • sstat_fragmentation_point - 发生 SCTP 分片的消息大小

    • sstat_primary - 有关当前主对等地址的信息(有关 #sctp_paddrinfo{} 的格式,请参见下文)

  • {sctp_get_peer_addr_info, #sctp_paddrinfo{}}

    #sctp_paddrinfo{
          assoc_id  = assoc_id(),
          address   = {IP, Port},
          state     = inactive | active | unconfirmed,
          cwnd      = integer(),
          srtt      = integer(),
          rto       = integer(),
          mtu       = integer()
    }
    IP = ip_address()
    Port = port_number()

    此选项为只读。它确定由 assoc_id 指定的关联中由 address 指定的对等地址的特定参数。字段 address 必须由调用者设置;所有其他字段在返回时填充。如果 assoc_id = 0(默认),则 address 将自动转换为相应的关联 ID。此选项很少使用。有关所有字段的语义,请参阅 RFC 2960SCTP 的套接字 API 扩展

SCTP 示例

Erlang SCTP 服务器的示例,该服务器接收 SCTP 消息并在标准输出上打印它们

-module(sctp_server).

-export([server/0,server/1,server/2]).
-include_lib("kernel/include/inet.hrl").
-include_lib("kernel/include/inet_sctp.hrl").

server() ->
    server(any, 2006).

server([Host,Port]) when is_list(Host), is_list(Port) ->
    {ok, #hostent{h_addr_list = [IP|_]}} = inet:gethostbyname(Host),
    io:format("~w -> ~w~n", [Host, IP]),
    server([IP, list_to_integer(Port)]).

server(IP, Port) when is_tuple(IP) orelse IP == any orelse IP == loopback,
                      is_integer(Port) ->
    {ok,S} = gen_sctp:open(Port, [{recbuf,65536}, {ip,IP}]),
    io:format("Listening on ~w:~w. ~w~n", [IP,Port,S]),
    ok     = gen_sctp:listen(S, true),
    server_loop(S).

server_loop(S) ->
    case gen_sctp:recv(S) of
    {error, Error} ->
        io:format("SCTP RECV ERROR: ~p~n", [Error]);
    Data ->
        io:format("Received: ~p~n", [Data])
    end,
    server_loop(S).

Erlang SCTP 客户端与上述服务器交互的示例。请注意,在此示例中,客户端创建与服务器的关联,其中包含 5 个出站流。因此,在流 0 上发送 "Test 0" 成功,但在流 5 上发送 "Test 5" 失败。然后,客户端 abort 该关联,这会导致在服务器端接收到相应的事件。

-module(sctp_client).

-export([client/0, client/1, client/2]).
-include_lib("kernel/include/inet.hrl").
-include_lib("kernel/include/inet_sctp.hrl").

client() ->
    client([localhost]).

client([Host]) ->
    client(Host, 2006);

client([Host, Port]) when is_list(Host), is_list(Port) ->
    client(Host,list_to_integer(Port)),
    init:stop().

client(Host, Port) when is_integer(Port) ->
    {ok,S}     = gen_sctp:open(),
    {ok,Assoc} = gen_sctp:connect
        (S, Host, Port, [{sctp_initmsg,#sctp_initmsg{num_ostreams=5}}]),
    io:format("Connection Successful, Assoc=~p~n", [Assoc]),

    io:write(gen_sctp:send(S, Assoc, 0, <<"Test 0">>)),
    io:nl(),
    timer:sleep(10000),
    io:write(gen_sctp:send(S, Assoc, 5, <<"Test 5">>)),
    io:nl(),
    timer:sleep(10000),
    io:write(gen_sctp:abort(S, Assoc)),
    io:nl(),

    timer:sleep(1000),
    gen_sctp:close(S).

一个简单的 Erlang SCTP 客户端,它使用 connect_init API

-module(ex3).

-export([client/4]).
-include_lib("kernel/include/inet.hrl").
-include_lib("kernel/include/inet_sctp.hrl").

client(Peer1, Port1, Peer2, Port2)
  when is_tuple(Peer1), is_integer(Port1), is_tuple(Peer2), is_integer(Port2) ->
    {ok,S}     = gen_sctp:open(),
    SctpInitMsgOpt = {sctp_initmsg,#sctp_initmsg{num_ostreams=5}},
    ActiveOpt = {active, true},
    Opts = [SctpInitMsgOpt, ActiveOpt],
    ok = gen_sctp:connect(S, Peer1, Port1, Opts),
    ok = gen_sctp:connect(S, Peer2, Port2, Opts),
    io:format("Connections initiated~n", []),
    client_loop(S, Peer1, Port1, undefined, Peer2, Port2, undefined).

client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) ->
    receive
        {sctp, S, Peer1, Port1, {_Anc, SAC}}
          when is_record(SAC, sctp_assoc_change), AssocId1 == undefined ->
            io:format("Association 1 connect result: ~p. AssocId: ~p~n",
                      [SAC#sctp_assoc_change.state,
                       SAC#sctp_assoc_change.assoc_id]),
            client_loop(S, Peer1, Port1, SAC#sctp_assoc_change.assoc_id,
                        Peer2, Port2, AssocId2);

        {sctp, S, Peer2, Port2, {_Anc, SAC}}
          when is_record(SAC, sctp_assoc_change), AssocId2 == undefined ->
            io:format("Association 2 connect result: ~p. AssocId: ~p~n",
                      [SAC#sctp_assoc_change.state, SAC#sctp_assoc_change.assoc_id]),
            client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2,
                       SAC#sctp_assoc_change.assoc_id);

        {sctp, S, Peer1, Port1, Data} ->
            io:format("Association 1: received ~p~n", [Data]),
            client_loop(S, Peer1, Port1, AssocId1,
                        Peer2, Port2, AssocId2);

        {sctp, S, Peer2, Port2, Data} ->
            io:format("Association 2: received ~p~n", [Data]),
            client_loop(S, Peer1, Port1, AssocId1,
                        Peer2, Port2, AssocId2);

        Other ->
            io:format("Other ~p~n", [Other]),
            client_loop(S, Peer1, Port1, AssocId1,
                        Peer2, Port2, AssocId2)

    after 5000 ->
            ok
    end.

另请参阅

gen_tcpgen_udpinetRFC 2960(流控制传输协议)、SCTP 的套接字 API 扩展

摘要

类型:导出的数据类型

关联 ID。

SCTP 套接字选项名称和值,用于设置。

SCTP 套接字选项名称,用于获取。

SCTP 套接字选项名称和值,您获取的内容。

open/* 返回的套接字标识符。

函数

中止关联。

关闭 SCTP 套接字。

与对等方建立关联。

与对等方建立关联。

开始与对等方建立关联。

开始与对等方建立关联。

开始与对等方建立关联(多个地址)。

开始与对等方建立关联(多个地址)。

更改套接字的控制进程(所有者)。

正常终止关联。

将错误号转换为字符串或原子。

使 SCTP 套接字侦听传入的关联。

等效于 open([])

创建 SCTP 套接字。

将关联分支到类型为 stream 的新套接字中。

接收 Data 消息。

发送一个功能齐全的 Data 消息。

发送数据消息。

类型:导出的数据类型

-type assoc_id() :: term().

关联 ID。

在例如 #sctp_paddr_change{} 中返回的不透明项,它标识 SCTP 套接字的关联。该项是不透明的,除了特殊值 0,它具有诸如“整个端点”或“所有未来关联”之类的含义。

-type option() :: elementary_option() | record_option().

SCTP 套接字选项名称和值,用于设置。

-type option_name() :: elementary_option_name() | record_option() | ro_option().

SCTP 套接字选项名称,用于获取。

-type option_value() :: elementary_option() | record_option() | ro_option().

SCTP 套接字选项名称和值,您获取的内容。

-type sctp_socket() :: port().

open/* 返回的套接字标识符。

类型:内部数据类型

链接到此类型

elementary_option()

查看源 (未导出)
-type elementary_option() ::
          {active, true | false | once | -32768..32767} |
          {buffer, non_neg_integer()} |
          {non_block_send, boolean()} |
          {debug, boolean()} |
          {dontroute, boolean()} |
          {exclusiveaddruse, boolean()} |
          {high_msgq_watermark, pos_integer()} |
          {linger, {boolean(), non_neg_integer()}} |
          {low_msgq_watermark, pos_integer()} |
          {mode, list | binary} |
          list | binary |
          {priority, non_neg_integer()} |
          {recbuf, non_neg_integer()} |
          {reuseaddr, boolean()} |
          {reuseport, boolean()} |
          {reuseport_lb, boolean()} |
          {ipv6_v6only, boolean()} |
          {sndbuf, non_neg_integer()} |
          {sctp_autoclose, non_neg_integer()} |
          {sctp_disable_fragments, boolean()} |
          {sctp_i_want_mapped_v4_addr, boolean()} |
          {sctp_maxseg, non_neg_integer()} |
          {sctp_nodelay, boolean()} |
          {tos, non_neg_integer()} |
          {tclass, non_neg_integer()} |
          {ttl, non_neg_integer()} |
          {recvtos, boolean()} |
          {recvtclass, boolean()} |
          {recvttl, boolean()}.
链接到此类型

elementary_option_name()

查看源 (未导出)
-type elementary_option_name() ::
          active | buffer | non_block_send | debug | dontroute | exclusiveaddruse |
          high_msgq_watermark | linger | low_msgq_watermark | mode | priority | recbuf | reuseaddr |
          reuseport | reuseport_lb | ipv6_v6only | sctp_autoclose | sctp_disable_fragments |
          sctp_i_want_mapped_v4_addr | sctp_maxseg | sctp_nodelay | sndbuf | tos | tclass | ttl |
          recvtos | recvtclass | recvttl.
链接到此类型

record_option()

查看源 (未导出)
-type record_option() ::
          {sctp_adaptation_layer, #sctp_setadaptation{adaptation_ind :: term()}} |
          {sctp_associnfo,
           #sctp_assocparams{assoc_id :: term(),
                             asocmaxrxt :: term(),
                             number_peer_destinations :: term(),
                             peer_rwnd :: term(),
                             local_rwnd :: term(),
                             cookie_life :: term()}} |
          {sctp_default_send_param,
           #sctp_sndrcvinfo{stream :: term(),
                            ssn :: term(),
                            flags :: term(),
                            ppid :: term(),
                            context :: term(),
                            timetolive :: term(),
                            tsn :: term(),
                            cumtsn :: term(),
                            assoc_id :: term()}} |
          {sctp_delayed_ack_time, #sctp_assoc_value{assoc_id :: term(), assoc_value :: term()}} |
          {sctp_events,
           #sctp_event_subscribe{data_io_event :: term(),
                                 association_event :: term(),
                                 address_event :: term(),
                                 send_failure_event :: term(),
                                 peer_error_event :: term(),
                                 shutdown_event :: term(),
                                 partial_delivery_event :: term(),
                                 adaptation_layer_event :: term(),
                                 authentication_event :: term()}} |
          {sctp_initmsg,
           #sctp_initmsg{num_ostreams :: term(),
                         max_instreams :: term(),
                         max_attempts :: term(),
                         max_init_timeo :: term()}} |
          {sctp_peer_addr_params,
           #sctp_paddrparams{assoc_id :: term(),
                             address :: term(),
                             hbinterval :: term(),
                             pathmaxrxt :: term(),
                             pathmtu :: term(),
                             sackdelay :: term(),
                             flags :: term()}} |
          {sctp_primary_addr, #sctp_prim{assoc_id :: term(), addr :: term()}} |
          {sctp_rtoinfo,
           #sctp_rtoinfo{assoc_id :: term(), initial :: term(), max :: term(), min :: term()}} |
          {sctp_set_peer_primary_addr, #sctp_setpeerprim{assoc_id :: term(), addr :: term()}}.
链接到此类型

ro_option()

查看源 (未导出)
-type ro_option() ::
          {sctp_get_peer_addr_info,
           #sctp_paddrinfo{assoc_id :: term(),
                           address :: term(),
                           state :: term(),
                           cwnd :: term(),
                           srtt :: term(),
                           rto :: term(),
                           mtu :: term()}} |
          {sctp_status,
           #sctp_status{assoc_id :: term(),
                        state :: term(),
                        rwnd :: term(),
                        unackdata :: term(),
                        penddata :: term(),
                        instrms :: term(),
                        outstrms :: term(),
                        fragmentation_point :: term(),
                        primary :: term()}}.

函数

链接到此函数

abort(Socket, Assoc)

查看源
-spec abort(Socket, Assoc) -> ok | {error, inet:posix()}
               when
                   Socket :: sctp_socket(),
                   Assoc ::
                       #sctp_assoc_change{state :: term(),
                                          error :: term(),
                                          outbound_streams :: term(),
                                          inbound_streams :: term(),
                                          assoc_id :: term()}.

中止关联。

异常终止由 Assoc 指定的关联,而不刷新未发送的数据。套接字本身保持打开状态。在此套接字上打开的其他关联仍然有效,并且该套接字可以在新的关联中使用。

-spec close(Socket) -> ok | {error, inet:posix()} when Socket :: sctp_socket().

关闭 SCTP 套接字。

关闭套接字及其上的所有关联。未发送的数据会像 eof/2 一样刷新。close/1 调用是阻塞的,具体取决于 linger 套接字[选项]的值。如果它是 false 或延迟超时时间到期,则调用返回,并且未发送的数据在后台刷新。

链接到此函数

connect(Socket, SockAddr, Opts)

查看源 (自 OTP 24.3 起)
-spec connect(Socket, SockAddr, Opts) ->
                 {ok,
                  #sctp_assoc_change{state :: comm_up,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error,
                  #sctp_assoc_change{state :: cant_assoc,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error, inet:posix()}
                 when
                     Socket :: sctp_socket(),
                     SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                     Opts :: [Opt :: option()].

等效于 connect(Socket, SockAddr, Opts, infinity)

-spec connect(Socket, SockAddr, Opts, Timeout) ->
                 {ok,
                  #sctp_assoc_change{state :: comm_up,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error,
                  #sctp_assoc_change{state :: cant_assoc,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error, inet:posix()}
                 when
                     Socket :: sctp_socket(),
                     SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                     Opts :: [Opt :: option()],
                     Timeout :: timeout();
             (Socket, Addr, Port, Opts) ->
                 {ok,
                  #sctp_assoc_change{state :: comm_up,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error,
                  #sctp_assoc_change{state :: cant_assoc,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error, inet:posix()}
                 when
                     Socket :: sctp_socket(),
                     Addr :: inet:ip_address() | inet:hostname(),
                     Port :: inet:port_number(),
                     Opts :: [Opt :: option()].

与对等方建立关联。

使用参数 AddrPort,等效于 connect(Socket, Addr, Port, Opts, infinity)

使用参数 SockAddrOpts (自 OTP 24.3 起),等效于 connect(Socket, Addr, Port, Opts, Timeout),其中 AddrPortSockAddr 中提取。

链接到此函数

connect(Socket, Addr, Port, Opts, Timeout)

查看源
-spec connect(Socket, Addr, Port, Opts, Timeout) ->
                 {ok,
                  #sctp_assoc_change{state :: comm_up,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error,
                  #sctp_assoc_change{state :: cant_assoc,
                                     error :: term(),
                                     outbound_streams :: term(),
                                     inbound_streams :: term(),
                                     assoc_id :: term()}} |
                 {error, inet:posix()}
                 when
                     Socket :: sctp_socket(),
                     Addr :: inet:ip_address() | inet:hostname(),
                     Port :: inet:port_number(),
                     Opts :: [Opt :: option()],
                     Timeout :: timeout().

与对等方建立关联。

为套接字 Socket 建立与 AddrPort 指定的对等方(SCTP 服务器套接字)的新关联。Timeout 以毫秒为单位表示。一个套接字可以与多个对等方关联。该套接字必须是 seqpacket 类型。

警告

使用小于操作系统建立关联所需的最大时间(如果使用 RFC 4960 中的默认值,大约为 4.5 分钟)的 Timeout 值,可能会导致不一致或不正确的返回值。当关联共享相同的 Socket(即源地址和端口)时,这一点尤其重要,因为控制进程会阻塞,直到 connect/* 返回。connect_init/* 提供了一种没有此限制的替代方案。

#sctp_assoc_change{}

connect/* 的结果是一个 #sctp_assoc_change{} 事件,其中特别包含新的 关联 ID:l

#sctp_assoc_change{
      state             = atom(),
      error             = integer(),
      outbound_streams  = integer(),
      inbound_streams   = integer(),
      assoc_id          = assoc_id()
}

可以通过为 connect 提供一个 sctp_initmsg 选项来设置关联的传出和传入流的数量,如下所示:

connect(Socket, Ip, Port>,
      [{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams,
                                   max_instreams=MaxInStreams}}])

在尝试关联之前,会在套接字上设置所有选项 Opt。如果选项记录具有未定义的字段值,则首先从套接字读取这些值的选项记录。实际上,Opt 选项记录只需要定义在连接之前要更改的字段值即可。

返回的 outbound_streamsinbound_streams 是套接字上的流数量。如果对等方要求较低的值,则这些值可能与请求的值(分别为 OutStreamsMaxInStreams)不同。

state 可以具有以下值:

  • comm_up - 关联已成功建立。这表示 connect 已成功完成。

  • cant_assoc - 无法建立关联(connect/* 失败)。

其他状态通常不会出现在 connect/* 的输出中。相反,它们可能会出现在 #sctp_assoc_change{} 事件中,这些事件不是从 recv/* 调用或套接字消息接收到的数据。所有这些都表示由于各种错误情况而丢失了关联,并且为了完整性在此处列出:

  • comm_lost

  • restart

  • shutdown_comp

字段 error 可以提供更详细的诊断信息。可以使用 error_string/1 将其值转换为字符串。

链接到此函数

connect_init(Socket, SockAddr, Opts)

查看源代码 (自 OTP 24.3 起)
-spec connect_init(Socket, SockAddr, Opts) -> ok | {error, inet:posix()}
                      when
                          Socket :: sctp_socket(),
                          SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                          Opts :: [option()].

等效于 connect_init(Socket, SockAddr, Opts, infinity)

链接到此函数

connect_init/4

查看源代码 (自 OTP R13B04 起)
-spec connect_init(Socket, SockAddr, Opts, Timeout) -> ok | {error, inet:posix()}
                      when
                          Socket :: sctp_socket(),
                          SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                          Opts :: [option()],
                          Timeout :: timeout();
                  (Socket, Addr, Port, Opts) -> ok | {error, inet:posix()}
                      when
                          Socket :: sctp_socket(),
                          Addr :: inet:ip_address() | inet:hostname(),
                          Port :: inet:port_number(),
                          Opts :: [option()].

开始与对等方建立关联。

使用参数 AddrPort,等效于 connect_init(Socket, Addr, Port, Opts, infinity)

使用参数 SockAddrOpts (自 OTP 24.3 起),等效于 connect_init(Socket, Addr, Port, Opts, Timeout),其中 AddrPort 是从 SockAddr 中提取的。

链接到此函数

connect_init(Socket, Addr, Port, Opts, Timeout)

查看源代码 (自 OTP R13B04 起)
-spec connect_init(Socket, Addr, Port, Opts, Timeout) -> ok | {error, inet:posix()}
                      when
                          Socket :: sctp_socket(),
                          Addr :: inet:ip_address() | inet:hostname(),
                          Port :: inet:port_number(),
                          Opts :: [option()],
                          Timeout :: timeout().

开始与对等方建立关联。

为套接字 Socket 发起一个新的关联,对等方(SCTP 服务器套接字)由 AddrPort 指定。

此 API 和 connect/* 的根本区别在于返回值是底层操作系统 connect(2) 系统调用的返回值。如果返回 ok,则表示操作已成功发起,并且关联建立的最终结果将作为 #sctp_assoc_change{} 事件发送到套接字所有者(控制进程)。套接字所有者必须准备好接收此事件,recv/* 调用必须轮询,具体取决于 active 选项的值。

这些参数与 connect/* 的描述相同,除了 Timeout 值,因为对于此函数,超时仅适用于 Addrinet:hostname/0 时的名称解析。

链接到此函数

connectx_init(Socket, SockAddrs, Opts)

查看源代码 (自 OTP 25.0 起)
-spec connectx_init(Socket, SockAddrs, Opts) -> {ok, assoc_id()} | {error, inet:posix()}
                       when
                           Socket :: sctp_socket(),
                           SockAddrs ::
                               [{inet:ip_address(), inet:port_number()} |
                                inet:family_address() |
                                socket:sockaddr_in() |
                                socket:sockaddr_in6()],
                           Opts :: [option()].

开始与对等方建立关联(多个地址)。

connectx_init/5 类似,但使用套接字地址,并且没有 Timeout。由于地址不需要查找,并且连接是非阻塞的,因此此调用会立即返回。

每个套接字地址 port 的值必须相同或为零。至少一个套接字地址必须具有非零的 port

链接到此函数

connectx_init(Socket, Addrs, Port, Opts)

查看源代码 (自 OTP 25.0 起)
-spec connectx_init(Socket, Addrs, Port, Opts) -> {ok, assoc_id()} | {error, inet:posix()}
                       when
                           Socket :: sctp_socket(),
                           Addrs :: [inet:ip_address() | inet:hostname()],
                           Port :: inet:port_number() | atom(),
                           Opts :: [option()].

等效于 connectx_init(Socket, Addrs, Port, Opts, infinity)

链接到此函数

connectx_init(Socket, Addrs, Port, Opts, Timeout)

查看源代码 (自 OTP 25.0 起)
-spec connectx_init(Socket, Addrs, Port, Opts, Timeout) -> {ok, assoc_id()} | {error, inet:posix()}
                       when
                           Socket :: sctp_socket(),
                           Addrs :: [inet:ip_address() | inet:hostname()],
                           Port :: inet:port_number() | atom(),
                           Opts :: [option()],
                           Timeout :: timeout().

开始与对等方建立关联(多个地址)。

为套接字 Socket 发起一个新的关联,对等方(SCTP 服务器套接字)由 AddrsPort 指定。

此 API 与 connect_init/* 类似,只是使用底层操作系统 sctp_connectx(3) 系统调用,该调用接受多个目标地址。

如果成功,将返回关联 ID,该 ID 将在后续的 #sctp_assoc_change{} 事件中收到。

这些参数如 connect_init/5 中所述。

注意

此 API 允许操作系统在建立关联时使用所有 Addrs,但不保证它会这样做。因此,如果连接失败,用户可能希望为后续调用轮换地址的顺序。

链接到此函数

controlling_process(Socket, Pid)

查看源
-spec controlling_process(Socket, Pid) -> ok | {error, Reason}
                             when
                                 Socket :: sctp_socket(),
                                 Pid :: pid(),
                                 Reason :: closed | not_owner | badarg | inet:posix().

更改套接字的控制进程(所有者)。

Socket 分配一个新的控制进程 Pid。请参阅 gen_udp:controlling_process/2

链接到此函数

eof(Socket, Assoc)

查看源
-spec eof(Socket, Assoc) -> ok | {error, Reason}
             when
                 Socket :: sctp_socket(),
                 Assoc ::
                     #sctp_assoc_change{state :: term(),
                                        error :: term(),
                                        outbound_streams :: term(),
                                        inbound_streams :: term(),
                                        assoc_id :: term()},
                 Reason :: term().

正常终止关联。

正常终止由 Assoc 指定的关联,刷新所有未发送的数据。套接字本身保持打开状态。在此套接字上打开的其他关联仍然有效。套接字可以在新的关联中使用。

链接到此函数

error_string(ErrorNumber)

查看源
-spec error_string(ErrorNumber) -> ok | string() | unknown_error when ErrorNumber :: integer().

将错误号转换为字符串或原子。

将 SCTP 错误号(例如,从 #sctp_remote_error{}#sctp_send_failed{})转换为解释性字符串,或转换为原子 ok(表示没有错误)或 unknown_error(表示无法识别的整数)。

-spec listen(Socket, IsServer) -> ok | {error, Reason}
                when Socket :: sctp_socket(), IsServer :: boolean(), Reason :: term();
            (Socket, Backlog) -> ok | {error, Reason}
                when Socket :: sctp_socket(), Backlog :: integer(), Reason :: term().

使 SCTP 套接字侦听传入的关联。

套接字将侦听它绑定的 IP 地址和端口号。

对于 seqpacket 类型(套接字(默认))的套接字,参数 IsServer 必须是一个 boolean/0。与 stream 套接字相反,没有侦听队列长度。如果 IsServertrue,则套接字接受新的关联,即它变为 SCTP 服务器套接字。

对于 stream 类型套接字,参数 Backlog 设置与 TCP 相同的后备队列长度。

-spec open() -> {ok, Socket} | {error, inet:posix()} when Socket :: sctp_socket().

等效于 open([])

-spec open(Port) -> {ok, Socket} | {error, inet:posix()}
              when Port :: inet:port_number(), Socket :: sctp_socket();
          (Opts) -> {ok, Socket} | {error, inet:posix()}
              when
                  Opts :: [Opt],
                  Opt ::
                      {ifaddr, IP | SockAddr} |
                      {ip, IP} |
                      {port, Port} |
                      inet:address_family() |
                      {type, SockType} |
                      {netns, file:filename_all()} |
                      {bind_to_device, binary()} |
                      option(),
                  IP :: inet:ip_address() | any | loopback,
                  SockAddr :: socket:sockaddr_in() | socket:sockaddr_in6(),
                  Port :: inet:port_number(),
                  SockType :: seqpacket | stream,
                  Socket :: sctp_socket().

创建 SCTP 套接字。

使用参数 Port,等效于 open([{port, Port}]

创建一个 SCTP 套接字,并将其绑定到所有 {ip,IP}(或同义的 {ifaddr,IP})选项指定的本地地址(此功能称为 SCTP 多宿主)。默认的 IPPortany0,表示绑定到任何空闲端口上的所有本地地址。

也可以使用 {ifaddr, SockAddr},在这种情况下,它优先于 ipport 选项。但是,这些选项可以用于更新 ifaddr 的地址和端口(如果它们在选项列表中出现在 ifaddr 之后),尽管不建议这样做。

其他选项

  • inet6 - 为 IPv6 设置套接字。

  • inet - 为 IPv4 设置套接字。这是默认设置。

使用一组默认的套接字 选项。特别是,套接字以 二进制被动模式打开,SockType 为 seqpacket,并且具有相当大的 内核和驱动程序 缓冲区

当套接字处于 被动模式时,可以通过 recv/1,2 调用接收数据。

当套接字处于 主动模式时,接收到的数据会作为消息传递到控制进程。

{sctp, Socket, FromIP, FromPort, {AncData, Data}}

有关消息字段的描述,请参阅 recv/1,2

注意

不幸的是,此消息格式与具有辅助数据的 gen_udp 消息格式以及 recv/1,2 返回的元组格式略有不同。

-spec open(Port :: integer(), Opts :: [term()]) -> _.

等效于 open([{port, Port} | Opts])

链接到此函数

peeloff(Socket, Assoc)

查看源代码 (自 OTP R15B 起)
-spec peeloff(Socket, Assoc) -> {ok, NewSocket} | {error, Reason}
                 when
                     Socket :: sctp_socket(),
                     Assoc ::
                         #sctp_assoc_change{state :: term(),
                                            error :: term(),
                                            outbound_streams :: term(),
                                            inbound_streams :: term(),
                                            assoc_id :: term()} |
                         assoc_id(),
                     NewSocket :: sctp_socket(),
                     Reason :: term().

将关联分支到类型为 stream 的新套接字中。

套接字 Socket(必须为 seqpacket 类型;一对多样式)中现有的关联 Assoc 分支到类型为 stream(一对一样式)的新套接字 NewSocket 中。

现有的关联参数 Assoc 可以是 #sctp_assoc_change{} 记录,例如从 recv/*connect/* 返回的,或者从主动模式下的侦听套接字返回的。它也可以只是此类记录中的字段 assoc_id integer/0

-spec recv(Socket) -> {ok, {FromIP, FromPort, AncData, Data}} | {error, Reason}
              when
                  Socket :: sctp_socket(),
                  FromIP :: inet:ip_address(),
                  FromPort :: inet:port_number(),
                  AncData ::
                      [#sctp_sndrcvinfo{stream :: term(),
                                        ssn :: term(),
                                        flags :: term(),
                                        ppid :: term(),
                                        context :: term(),
                                        timetolive :: term(),
                                        tsn :: term(),
                                        cumtsn :: term(),
                                        assoc_id :: term()} |
                       inet:ancillary_data()],
                  Data ::
                      binary() |
                      string() |
                      #sctp_sndrcvinfo{stream :: term(),
                                       ssn :: term(),
                                       flags :: term(),
                                       ppid :: term(),
                                       context :: term(),
                                       timetolive :: term(),
                                       tsn :: term(),
                                       cumtsn :: term(),
                                       assoc_id :: term()} |
                      #sctp_assoc_change{state :: term(),
                                         error :: term(),
                                         outbound_streams :: term(),
                                         inbound_streams :: term(),
                                         assoc_id :: term()} |
                      #sctp_paddr_change{addr :: term(),
                                         state :: term(),
                                         error :: term(),
                                         assoc_id :: term()} |
                      #sctp_adaptation_event{adaptation_ind :: term(), assoc_id :: term()},
                  Reason ::
                      inet:posix() |
                      #sctp_send_failed{flags :: term(),
                                        error :: term(),
                                        info :: term(),
                                        assoc_id :: term(),
                                        data :: term()} |
                      #sctp_paddr_change{addr :: term(),
                                         state :: term(),
                                         error :: term(),
                                         assoc_id :: term()} |
                      #sctp_pdapi_event{indication :: term(), assoc_id :: term()} |
                      #sctp_remote_error{error :: term(), assoc_id :: term(), data :: term()} |
                      #sctp_shutdown_event{assoc_id :: term()}.

等效于 recv(Socket, infinity)

链接到此函数

recv(Socket, Timeout)

查看源
-spec recv(Socket, Timeout) -> {ok, {FromIP, FromPort, AncData, Data}} | {error, Reason}
              when
                  Socket :: sctp_socket(),
                  Timeout :: timeout(),
                  FromIP :: inet:ip_address(),
                  FromPort :: inet:port_number(),
                  AncData ::
                      [#sctp_sndrcvinfo{stream :: term(),
                                        ssn :: term(),
                                        flags :: term(),
                                        ppid :: term(),
                                        context :: term(),
                                        timetolive :: term(),
                                        tsn :: term(),
                                        cumtsn :: term(),
                                        assoc_id :: term()} |
                       inet:ancillary_data()],
                  Data ::
                      binary() |
                      string() |
                      #sctp_sndrcvinfo{stream :: term(),
                                       ssn :: term(),
                                       flags :: term(),
                                       ppid :: term(),
                                       context :: term(),
                                       timetolive :: term(),
                                       tsn :: term(),
                                       cumtsn :: term(),
                                       assoc_id :: term()} |
                      #sctp_assoc_change{state :: term(),
                                         error :: term(),
                                         outbound_streams :: term(),
                                         inbound_streams :: term(),
                                         assoc_id :: term()} |
                      #sctp_paddr_change{addr :: term(),
                                         state :: term(),
                                         error :: term(),
                                         assoc_id :: term()} |
                      #sctp_adaptation_event{adaptation_ind :: term(), assoc_id :: term()},
                  Reason ::
                      inet:posix() |
                      #sctp_send_failed{flags :: term(),
                                        error :: term(),
                                        info :: term(),
                                        assoc_id :: term(),
                                        data :: term()} |
                      #sctp_paddr_change{addr :: term(),
                                         state :: term(),
                                         error :: term(),
                                         assoc_id :: term()} |
                      #sctp_pdapi_event{indication :: term(), assoc_id :: term()} |
                      #sctp_remote_error{error :: term(), assoc_id :: term(), data :: term()} |
                      #sctp_shutdown_event{assoc_id :: term()}.

接收 Data 消息。

从套接字的任何关联接收 Data 消息。如果接收超时,则返回 {error,timeout}。默认超时为 infinityFromIPFromPort 指示发送方的地址。

AncData 是与主 Data 一起接收的辅助数据项列表。此列表可以为空,或者如果启用了接收辅助数据(请参阅选项 sctp_events),则可以包含一个 #sctp_sndrcvinfo{} 记录。默认情况下,它是启用的,因为此类辅助数据提供了一种简便的方法来确定接收消息的关联和流。(另一种方法是使用套接字选项 sctp_get_peer_addr_infoFromIPFromPort 获取关联 ID,但这仍然不提供流号)。

AncData 也可能包含来自套接字 选项 recvtosrecvtclassrecvttl辅助数据,如果平台支持该套接字。

接收到的 Data 可以根据套接字模式,是 binary/0 或字节(范围为 0255 的整数)的 list/0,或者它可以是 SCTP 事件。

可能的 SCTP 事件

  • #sctp_sndrcvinfo{}

  • #sctp_assoc_change{}

  • #sctp_paddr_change{
          addr      = {ip_address(),port()},
          state     = atom(),
          error     = integer(),
          assoc_id  = assoc_id()
    }

    表示由 addr 指定的对等方的 IP 地址在 assoc_id 关联中的状态更改。 state 的可能值(大部分不言自明)包括

    • addr_unreachable

    • addr_available

    • addr_removed

    • addr_added

    • addr_made_prim

    • addr_confirmed

    如果发生错误(例如,addr_unreachable),则字段 error 提供更多诊断信息。在这种情况下,事件 #sctp_paddr_change{} 会自动转换为 recv 返回的 error 项。可以使用 error_string/1error 字段值转换为字符串。

  • #sctp_send_failed{
          flags     = true | false,
          error     = integer(),
          info      = #sctp_sndrcvinfo{},
          assoc_id  = assoc_id()
          data      = binary()
    }

    如果发送操作失败,发送者可以接收此事件。

    • flags - 一个布尔值,指定数据是否已通过网络传输。

    • error - 提供扩展的诊断信息,请使用 error_string/1

    • info - 失败的 send/* 中使用的原始 #sctp_sndrcvinfo{} 记录。

    • data - 尝试发送的整个原始数据块。

    在当前 Erlang/SCTP 绑定的实现中,此事件在内部转换为 recv/* 返回的 error 项。

  • #sctp_adaptation_event{
          adaptation_ind = integer(),
          assoc_id       = assoc_id()
    }

    当对等方发送自适应层指示参数(通过选项 sctp_adaptation_layer 配置)时传递。请注意,在当前 Erlang/SCTP 绑定的实现中,此事件默认情况下处于禁用状态。

  • #sctp_pdapi_event{
          indication = sctp_partial_delivery_aborted,
          assoc_id   = assoc_id()
    }

    部分传递失败。在当前 Erlang/SCTP 绑定的实现中,此事件在内部转换为 recv/* 返回的 error 项。

链接到此函数

send(Socket, SndRcvInfo, Data)

查看源
-spec send(Socket, SndRcvInfo, Data) -> ok | {error, Reason}
              when
                  Socket :: sctp_socket(),
                  SndRcvInfo ::
                      #sctp_sndrcvinfo{stream :: term(),
                                       ssn :: term(),
                                       flags :: term(),
                                       ppid :: term(),
                                       context :: term(),
                                       timetolive :: term(),
                                       tsn :: term(),
                                       cumtsn :: term(),
                                       assoc_id :: term()},
                  Data :: binary() | iolist(),
                  Reason :: term().

发送一个功能齐全的 Data 消息。

使用 #sctp_sndrcvinfo{} 记录中的所有发送参数发送 Data 消息。这样,用户可以指定 PPID(传递到远程端)和上下文(传递到本地 SCTP 层),例如,可用于错误识别。但是,很少需要这种细粒度的用户控制。函数 send/4 对于大多数应用程序来说足够了。

注意

发送通常是阻塞的,但如果套接字选项 non_block_send 设置为 true,则在函数会阻塞的情况下,该函数将返回例如 {error, eagain}。然后,由用户稍后重试。

链接到此函数

send(Socket, Assoc, Stream, Data)

查看源
-spec send(Socket, Assoc, Stream, Data) -> ok | {error, Reason}
              when
                  Socket :: sctp_socket(),
                  Assoc ::
                      #sctp_assoc_change{state :: term(),
                                         error :: term(),
                                         outbound_streams :: term(),
                                         inbound_streams :: term(),
                                         assoc_id :: term()} |
                      assoc_id(),
                  Stream :: integer(),
                  Data :: binary() | iolist(),
                  Reason :: term().

发送数据消息。

在关联 AssocStream 上发送 Data 消息。

Assoc 可以使用来自关联建立的 #sctp_assoc_change{} 记录指定,也可以使用 assoc_id/0 integer/0 字段值指定。

注意

发送通常是阻塞的,但如果套接字选项 non_block_send 设置为 true,则在函数会阻塞的情况下,该函数将返回例如 {error, eagain}。然后,由用户稍后重试。