2012-03-08 36 views
2

我建立了一個很幼稚的並行SSL受體。二郎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似乎不能接收任何消息。該程序的運行示例如下:

1> multiserver:start(). 
<0.34.0> 

然後我調用客戶端/ 1三次從不同的外殼:

首先,我在外殼1 殼牌1啓動服務器。 Shell 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 

這是打印輸出到服務器shell。 殼牌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模塊做到這一點嗎?

+0

看來,我運行到同樣的問題...你有關於它的任何信息嗎? – TheSquad 2012-04-10 09:35:52

+0

不,解決方法是在不同的shell中運行客戶端。但我想知道發生了什麼,爲什麼使用SSL不可能,而gen_tcp沒有問題。 – christofferp 2012-04-26 06:27:24

回答

2

的原因超時是,在第二過程使用套接字選項{活性,FALSE},即接收將永遠不會得到任何消息。

erlang docs for the ssl module指出插座通過調用transport_accept/1應該繼承監聽套接字設置的選項創建的。第一個進程在transport_accept/3時繼承這些選項,但由於某些原因,第二個進程沒有。 您可以檢查選項與

ssl:getopts(ClientSocket,[mode, active]) 

我不知道爲什麼會這樣,但一個解決方法是明確設置新接受的套接字上的選項

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