简体   繁体   中英

tcp server and client interaction

I have a tcp server(echo server) accepting connections. I have a client which when given a parameter N, creates those many processes trying to connect with the tcp listener. I am able to connect to those sockets but I can see many sockets being closed which is evident since I am using an echo server, I am not receiving messages back that I sent.

Here is the server code( crucial part)

 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.

Client that connects to the server. Creating N processes that connect to the server and then use the returned socket to communicate.

     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.

The error is on your server, you are pattern matching a messa like this on a tcp closed:

{error, closed} 

but if you go to the documentantion for gen_tcp , you will notice that you should pattern match these messages:

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

Update your code with:

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.

and you should start getting the CLOSED string on your screen

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM