tcp服务器和客户端交互

Posted

技术标签:

【中文标题】tcp服务器和客户端交互【英文标题】:tcp server and client interaction 【发布时间】:2016-07-28 22:16:11 【问题描述】:

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

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

 init(State = #stateport = 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#statelsocket = LSocket,
   spawn(fun() -> accept(NewState) end),
   ok, NewState;
   error, Reason ->
    stop, Reason
  end.


  accept(State = #statelsocket = 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#statelow = 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】:

错误出现在您的服务器上,您正在与关闭的 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 字符串

【讨论】:

以上是关于tcp服务器和客户端交互的主要内容,如果未能解决你的问题,请参考以下文章

Java网络编程(TCP协议-服务端和客户端交互)

TCP网络程序实例——服务器端与客户端交互

Java网络编程TCP程序,服务器和客户机交互流程以及基本操作步骤。

Java 客户端混合 TCP 和 UDP 功能

客户端服务端交互(TCP) java

[转]HTTP报文接口及客户端和服务器端交互原理