1

我有一个 tcp 服务器(回显服务器)接受连接。我有一个客户端,当给定参数 N 时,它会创建许多试图与 tcp 侦听器连接的进程。我能够连接到这些套接字,但我可以看到许多套接字被关闭,这很明显,因为我使用的是回显服务器,我没有收到我发送的消息。

这是服务器代码(关键部分)

 init(State = #state{port = Port}) ->
 ets:new(csockets, [ordered_set, named_table, public]),
 ets:insert(csockets, {sockets, []}),
 case gen_tcp:listen(Port, ?TCP_OPTIONS) of
   {ok, LSocket} ->
   NewState = State#state{lsocket = LSocket},
   spawn(fun() -> accept(NewState) end),
   {ok, NewState};
   {error, Reason} ->
    {stop, Reason}
  end.


  accept(State = #state{lsocket = LSocket}) ->
  case gen_tcp:accept(LSocket) of
   {ok, Socket} ->
   {sockets, List} = hd(ets:lookup(csockets, sockets)),
   NewList = [Socket | List],
   ets:insert(csockets, {sockets, NewList}),
   Pid = spawn(fun() ->
    loop(Socket)
              end),
    gen_tcp:controlling_process(Socket, Pid),
    accept(State);
    {error, closed} -> State
    end.


   loop(Socket) ->
   case gen_tcp:recv(Socket, 0) of
   {ok, Data} ->
   gen_tcp:send(Socket, Data),
   loop(Socket);
    {error, closed} ->
    io:format("CLOSED ~n"),  %% This asserts for many sockets
    ok
    end.

连接到服务器的客户端。创建 N 个进程连接到服务器,然后使用返回的套接字进行通信。

     send(State = #state{}) ->
     Low = State#state.low,
     High = State#state.high + 1,
     case Low of
      High -> State;
      _Else ->
      N = Low rem 10,
      Dest = lists:nth(1, State#state.dest),
      spawn(?MODULE, loop, [Dest, Low]),
      NewState = State#state{low = Low + 1},
       send(NewState)
      end.

      loop({IP, Port}, Low) ->
      case gen_tcp:connect(IP, Port, [binary, {active, true}]) of
      {ok, Socket} ->
       io:format("~p Connected ~n", [Low]),
       gen_tcp:send(Socket, "Hi"),
      receive
       {tcp, RecPort, Data} ->
       io:format("I have received ~p on port ~p ~n", [Data, RecPort])
      end;
      _Else ->
      io:format("The connection failed ~n")
      loop({IP, Port}, Low)
      end.
4

1 回答 1

1

错误在您的服务器上,您在 tcp 关闭时正在模式匹配这样的消息:

{error, closed} 

但是,如果您查看gen_tcp的文档,您会注意到您应该对这些消息进行模式匹配:

{tcp_closed, Socket}
{tcp_error, Socket, Reason}

更新您的代码:

loop(Socket) ->
    case gen_tcp:recv(Socket, 0) of
        {ok, Data} ->
            gen_tcp:send(Socket, Data),
            loop(Socket);
        {tcp_error, Socket} ->
            io:format("CLOSED ~n"),  %% This asserts for many sockets
            ok
    end.

你应该开始在屏幕上看到 CLOSED 字符串

于 2016-04-08T16:20:15.370 回答