在localhost上测试具有多个客户端的并发服务器:error,econnrefused

时间:2017-05-22 03:51:31

标签: erlang gen-tcp

我无法让多个客户端与我的并发echo服务器通信。以下是我的结果:

服务器终端窗口:

1> c(s).
{ok,s}

2> s:init(15555).
Server started on port: 15555

客户端终端窗口:

1> c(cl).
{ok,cl}

2> cl:test().
[<0.64.0>,<0.65.0>,<0.66.0>,<0.67.0>,<0.68.0>]

3> 
=ERROR REPORT==== 21-May-2017::21:21:39 ===
Error in process <0.68.0> with exit value:
{{badmatch,{error,econnrefused}},[{cl,client,2,[{file,"cl.erl"},{line,5}]}]}

=ERROR REPORT==== 21-May-2017::21:21:39 ===
Error in process <0.67.0> with exit value:
{{badmatch,{error,econnrefused}},[{cl,client,2,[{file,"cl.erl"},{line,5}]}]}
...
...

在shell中,如果我启动服务器,然后连接一个客户端,我的客户端和服务器可以无错误地来回通信:

服务器终端窗口:

1> c(s).
{ok,s}

2> s:init(15555).
Server started on port: 15555

客户端终端窗口:

1> c(cl).  
{ok,cl}

2> cl:client(1, 15555).
Client1: sent -->hello
Client1: received <--hello
ok

在我失败的并发测试中,我这样做:

test() ->
    Port = 1555,
    [spawn(?MODULE, client, [Id, Port]) || Id <- lists:seq(1, 5)].

这是我的echo服务器:

-module(s).
-compile(export_all).

init(Port) ->
    {ok, ServerSocket} = gen_tcp:listen(Port, [binary, {active,true},
                                               {packet,4}, {reuseaddr,true}] ),
    io:format("Server started on port: ~w~n", [Port]),
    server(ServerSocket).

server(ServerSocket) ->
    {ok, ClientSocket} = gen_tcp:accept(ServerSocket),
    spawn(?MODULE, server, [ServerSocket]),

    timer:sleep(rand:uniform(3) * 1000),
    loop(ClientSocket).


loop(ClientSocket) ->
    receive
        {tcp, ClientSocket, CompleteMsg} ->
            io:format("Server: received ~s~n", [CompleteMsg]),
            gen_tcp:send(ClientSocket, CompleteMsg);
        {tcp_closed, ClientSocket} ->
            io:format("Server: client closed socket.~n")
    end,
    loop(ClientSocket).

这是我的客户:

-module(cl).
-compile(export_all).

client(Id, Port) ->
    {ok, Socket} = gen_tcp:connect(localhost, Port, [binary, {active,true}, 
                                                      {packet,4},
                                                      {reuseaddr, true}] ),
    Msg = "hello",
    gen_tcp:send(Socket, Msg),
    io:format("Client~w: sent -->~s~n", [Id, Msg]),

    receive 
        {tcp, Socket, CompleteMsg} ->
            io:format("Client~w: received <--~s~n", [Id, CompleteMsg]);
        {tcp_closed, Socket} ->
            io:format("Server closed the socket.~n")
    end,
    gen_tcp:close(Socket).

test() ->
    Port = 1555,
    [spawn(?MODULE, client, [Id, Port]) || Id <- lists:seq(1, 5)].

我的理解是TCP socket只不过是一个包含四个数字的元组:

{senderPort, senderAddress, destinationPort, destinationAddress}

我认为我的每个客户端必须具有相同的senderPortsenderAddress,因此他们都在尝试使用相同的TCP套接字。但我认为我的一个客户端能够成功建立TCP连接,而其余客户端连接被拒绝错误,但我的所有并发客户端都拒绝连接错误。

在我看来,gen_tcp:connect()以某种方式选择senderPort并检索senderAddress,它与ServerAddress和ServerPort参数一起定义了套接字。如何让每个客户端使用不同的senderPort,以便每个客户端创建一个唯一的套接字?

有没有办法以编程方式测试localhost上有多个客户端的并发服务器?

0 个答案:

没有答案