首页 文章

tcp服务器和客户端交互

提问于
浏览
1

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

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

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.

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字符串

相关问题