我在服务器 - 客户端模型中使用 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回复客户端消息?
谢谢和最诚挚的问候,
陈。
答案 0 :(得分:0)
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记录类型,而gen_sctp:send / 4仅为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().