【问题标题】:Erlang ssl non-blocking parallel acceptorsErlang ssl 非阻塞并行接受器
【发布时间】:2012-05-09 05:27:17
【问题描述】:

我已经构建了一个非常幼稚的并行 ssl 接受器。

-module(multiserver).
-export([start/0,client/1]).

%% This is a dummy SSL Erlang server/client example

start() ->
    spawn_link(fun() -> init([]) end).

init([]) ->
    ssl:start(),
    {ok, ListenSocket} = ssl:listen(9990, [{certfile, "cert.pem"}, {keyfile, "privkey.pem"} ,{reuseaddr, true},{active, true}, binary]),
    Pid = self(),
    spawn_link(fun() -> listener(ListenSocket, Pid, 1) end),
    spawn_link(fun() -> listener(ListenSocket, Pid, 2) end),

    loop().

loop() ->
    receive 
        {new, _Pid} ->
            %% Do stuff here
            loop()
    end.

listener(ListenSocket, Pid, Num) ->
    {ok, ClientSocket} = ssl:transport_accept(ListenSocket),
    ok = ssl:ssl_accept(ClientSocket),
    io:format("listener ~p accepted ~n", [Num]),

    ok = ssl:send(ClientSocket, "server"),
    io:format("listener ~p  sent~n", [Num]),

    receive
        X -> io:format("listener ~p: ~p ~n", [Num, X])
    after 5000 ->
            io:format("listener ~p timeout ~n", [Num]),
            timeout
    end,
    ssl:close(ClientSocket),

    listener(ListenSocket, Pid, Num).

client(Message) ->
    ssl:start(),
    {ok, Socket} = ssl:connect("localhost", 9990,  [binary, {active,true}], infinity),

    receive
        X -> io:format("~p ~n", [X])
    after 2000 ->
            timeout
    end,
    ok = ssl:send(Socket,  Message),    

    ssl:close(Socket),
    io:format("client closed~n").

我的问题是侦听器 2 似乎无法接收任何消息。该程序的示例运行如下所示:

首先我在 shell 1 中启动服务器。 外壳 1:

1> multiserver:start().
<0.34.0>

然后我从不同的 shell 调用 client/1 三次。 外壳 2:

2> multiserver:client("client").
{ssl,{sslsocket,new_ssl,<0.51.0>},<<"server">>} 
client closed
ok
3> multiserver:client("client").
{ssl,{sslsocket,new_ssl,<0.54.0>},<<"server">>} 
client closed
ok
4> multiserver:client("client").
{ssl,{sslsocket,new_ssl,<0.56.0>},<<"server">>} 
client closed
ok

这是服务器外壳的打印输出。 外壳 1:

listener 1 accepted 
listener 1  sent
listener 1: {ssl,{sslsocket,new_ssl,<0.51.0>},<<"client">>} 
listener 2 accepted 
listener 2  sent
listener 1 accepted 
listener 1  sent
listener 1: {ssl,{sslsocket,new_ssl,<0.54.0>},<<"client">>} 
listener 2 timedout 
2> 

我已经花了几个小时来处理这个问题,但我无法理解为什么侦听器 2 无法接收任何数据。如果我编辑代码以使用 gen_tcp 它按预期工作。 有什么我想念的吗? 是否可以使用当前的 ssl 模块执行此操作?

【问题讨论】:

  • 我好像遇到了同样的问题...你有任何相关信息吗?
  • 不,解决方法是在不同的 shell 中运行客户端。但我想知道发生了什么,为什么在 gen_tcp 没有问题的情况下使用 SSL 是不可能的。

标签: ssl erlang


【解决方案1】:

超时的原因是在第二个进程中使用了socket选项{active,false},即receive永远不会收到任何消息。

erlang docs for the ssl module 声明通过调用 transport_accept/1 创建的套接字应该继承为侦听器套接字设置的选项。第一个进程在执行 transport_accept/3 时继承了选项,但由于某种原因,第二个进程没有。 您可以使用

检查选项
ssl:getopts(ClientSocket,[mode, active])

我不知道为什么会发生这种情况,但一种解决方法是在新接受的套接字上显式设置选项

ssl:setopts(ClientSocket, [{active,true}, {mode,binary}])

【讨论】:

    猜你喜欢
    • 2020-02-18
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 2014-06-07
    相关资源
    最近更新 更多