如何使用 gen_sctp:send/3
how to use gen_sctp:send/3
我正在使用 gen_sctp 在服务器-客户端模型中创建 soscket 和关联时做一个例子。
在服务器端:
{ok,serverSocket} = gen_sctp:open(1234,[{ip,{127,0,0,1}},{reuseaddr,true},{active,true}]).
ok = gen_sctp:listen(S,true).
在客户端:
{ok,Client} = gen_sctp:open(1243,[{ip,{127,0,0,1}},{reuseaddr,true}]).
{ok,Ass} = gen_sctp:connect(S,{127,0,0,1},1234,[{active,true}]).
然后客户端通过send/4:
向服务器发送消息
gen_sctp:send(S,Ass,2,<<"hellooooo">>).
服务器端接收消息:
{sctp,#Port<0.6126>,
{127,0,0,1},
1243,
{[{sctp_sndrcvinfo,2,1,[],0,0,0,1409953138,0,18}],
<<"hellooooo">>}}
那么服务器如何才能通过send/3向客户端回复消息呢?
谢谢并致以最诚挚的问候,
翻译
gen_sctp:send/3 类似于 gen_sctp:send/4 但您可以设置更多标志和选项。您已经在客户端代码中使用了 gen_sctp:send/4(当您弄乱了客户端和服务器套接字时):
{ok, Assoc} = gen_sctp:connect(ClientSocket, {127,0,0,1}, 1234,[{active,true}]).
gen_sctp:send(ClientSocket, Assoc, 2, <<"hellooooo">>).
而 Assoc 属于 sctp_assoc_change record type while gen_sctp:send/4 looks just for assoc_id if you provide sctp_assoc_change。因此,目前提供 #sctp_assoc_change{} 或只是关联 ID 的行为完全相同。
以及如何在服务器中找到客户端的关联ID?它在服务器收到的消息中提供:
{sctp,#Port<0.6126>,
{127,0,0,1},
1243,
{[{sctp_sndrcvinfo,2,1,[],0,0,0,1409953138,0,18}],
<<"hellooooo">>}}
#sctp_sdnrcvinfo{} 记录有字段告诉关联 ID 和从哪个数据接收的流编号。您可以从 assoc_id 字段获取当前关联 ID 并将其传递给另一个 gen_sctp:send/4:
gen_sctp:send(ServerSocket, AssocID, 2, <<"welcome!">>).
流编号为 2 可能不会使其失败,因为默认情况下 gen_sctp:open 生成 10 个传入和传出流,但您可以安全地提供 0 作为流编号。
下面是一个用sctp发送和接收数据的例子:
#!/usr/bin/escript
-include_lib("kernel/include/inet_sctp.hrl").
server_loop(Socket) ->
receive
{sctp, Socket, _FromIP, _FromPort, {[#sctp_sndrcvinfo{assoc_id=AssocID}],
Payload}} ->
gen_sctp:send(Socket, #sctp_sndrcvinfo{assoc_id=AssocID, stream=0},
<<"pong">>),
% or less complex gen_sctp:send/4
gen_sctp:send(Socket, AssocID, 0, <<"pong">>);
Rest ->
io:format("server got unhandled message ~w~n", [Rest])
end,
server_loop(Socket).
create_server_socket() ->
{ok, Socket} = gen_sctp:open(1234, [{ip,{127,0,0,1}}, {reuseaddr,true},
{active,true}]),
gen_sctp:listen(Socket, true),
{ok, Socket}.
run_server() ->
Spawner = self(),
spawn_link(fun() ->
{ok, Socket} = create_server_socket(), Spawner ! ready, server_loop(Socket)
end),
receive
ready ->
io:format("server is up~n"),
ok
after 100 ->
throw(server_timeout)
end.
ping_server() ->
{ok, Socket} = gen_sctp:open(1243, [{ip,{127,0,0,1}}, {reuseaddr, true}]),
{ok, AssocChange} = gen_sctp:connect(Socket, {127,0,0,1}, 1234, [{active, true}]),
gen_sctp:send(Socket, AssocChange, 2, <<"ping">>),
receive
{sctp, Socket, _FromIP, _FromPort, {[#sctp_sndrcvinfo{}], Payload}} ->
io:format("client got payload ~p~n", [Payload])
after 2000 ->
throw(client_timeout)
end.
main([]) ->
run_server(),
ping_server().
我正在使用 gen_sctp 在服务器-客户端模型中创建 soscket 和关联时做一个例子。
在服务器端:
{ok,serverSocket} = gen_sctp:open(1234,[{ip,{127,0,0,1}},{reuseaddr,true},{active,true}]).
ok = gen_sctp:listen(S,true).
在客户端:
{ok,Client} = gen_sctp:open(1243,[{ip,{127,0,0,1}},{reuseaddr,true}]).
{ok,Ass} = gen_sctp:connect(S,{127,0,0,1},1234,[{active,true}]).
然后客户端通过send/4:
向服务器发送消息gen_sctp:send(S,Ass,2,<<"hellooooo">>).
服务器端接收消息:
{sctp,#Port<0.6126>,
{127,0,0,1},
1243,
{[{sctp_sndrcvinfo,2,1,[],0,0,0,1409953138,0,18}],
<<"hellooooo">>}}
那么服务器如何才能通过send/3向客户端回复消息呢?
谢谢并致以最诚挚的问候,
翻译
gen_sctp:send/3 类似于 gen_sctp:send/4 但您可以设置更多标志和选项。您已经在客户端代码中使用了 gen_sctp:send/4(当您弄乱了客户端和服务器套接字时):
{ok, Assoc} = gen_sctp:connect(ClientSocket, {127,0,0,1}, 1234,[{active,true}]).
gen_sctp:send(ClientSocket, Assoc, 2, <<"hellooooo">>).
而 Assoc 属于 sctp_assoc_change record type while gen_sctp:send/4 looks just for assoc_id if you provide sctp_assoc_change。因此,目前提供 #sctp_assoc_change{} 或只是关联 ID 的行为完全相同。
以及如何在服务器中找到客户端的关联ID?它在服务器收到的消息中提供:
{sctp,#Port<0.6126>,
{127,0,0,1},
1243,
{[{sctp_sndrcvinfo,2,1,[],0,0,0,1409953138,0,18}],
<<"hellooooo">>}}
#sctp_sdnrcvinfo{} 记录有字段告诉关联 ID 和从哪个数据接收的流编号。您可以从 assoc_id 字段获取当前关联 ID 并将其传递给另一个 gen_sctp:send/4:
gen_sctp:send(ServerSocket, AssocID, 2, <<"welcome!">>).
流编号为 2 可能不会使其失败,因为默认情况下 gen_sctp:open 生成 10 个传入和传出流,但您可以安全地提供 0 作为流编号。
下面是一个用sctp发送和接收数据的例子:
#!/usr/bin/escript
-include_lib("kernel/include/inet_sctp.hrl").
server_loop(Socket) ->
receive
{sctp, Socket, _FromIP, _FromPort, {[#sctp_sndrcvinfo{assoc_id=AssocID}],
Payload}} ->
gen_sctp:send(Socket, #sctp_sndrcvinfo{assoc_id=AssocID, stream=0},
<<"pong">>),
% or less complex gen_sctp:send/4
gen_sctp:send(Socket, AssocID, 0, <<"pong">>);
Rest ->
io:format("server got unhandled message ~w~n", [Rest])
end,
server_loop(Socket).
create_server_socket() ->
{ok, Socket} = gen_sctp:open(1234, [{ip,{127,0,0,1}}, {reuseaddr,true},
{active,true}]),
gen_sctp:listen(Socket, true),
{ok, Socket}.
run_server() ->
Spawner = self(),
spawn_link(fun() ->
{ok, Socket} = create_server_socket(), Spawner ! ready, server_loop(Socket)
end),
receive
ready ->
io:format("server is up~n"),
ok
after 100 ->
throw(server_timeout)
end.
ping_server() ->
{ok, Socket} = gen_sctp:open(1243, [{ip,{127,0,0,1}}, {reuseaddr, true}]),
{ok, AssocChange} = gen_sctp:connect(Socket, {127,0,0,1}, 1234, [{active, true}]),
gen_sctp:send(Socket, AssocChange, 2, <<"ping">>),
receive
{sctp, Socket, _FromIP, _FromPort, {[#sctp_sndrcvinfo{}], Payload}} ->
io:format("client got payload ~p~n", [Payload])
after 2000 ->
throw(client_timeout)
end.
main([]) ->
run_server(),
ping_server().