【问题标题】:Keeping a server "live"保持服务器“活动”
【发布时间】:2014-01-21 06:32:06
【问题描述】:

我在 Erlang 中创建了一个服务器,但遇到了一个我无法解决的问题。我有我的服务器和一个客户端,服务器监听客户端发送一条消息,在控制台中输出它然后什么也不做。我试图让他“活着”等待很多客户的消息并回答他们。

这是代码

init(PortNumber) ->
server_logger:init(),

% default options = [data type, socket work mode]
DefaultOptions = [binary, {packet, 0}, {active, false}, {reuseaddr, true}],

case gen_tcp:listen(PortNumber, DefaultOptions) of
     {ok, ListenSocket} ->
        server_logger:print_fmsg("Listening on port: ~B", [PortNumber]),
        server_logger:print_newline(),
        server_logger:print_fmsg(": ", []),
        case gen_tcp:accept(ListenSocket) of
            {ok, Socket} ->
                {ok, Bin} = do_recv(Socket, []),
                ok = gen_tcp:close(Socket),
                Bin;
            {error, closed} ->
                server_logger:print_msg("The connection is closed and cannot listen.")
        end;
    {error, Reason} -> 
        server_logger:print_fmsg("Cannot listen, cause: ~w", [Reason])
 end.

do_recv(Socket, Bs) -> 
    case gen_tcp:recv(Socket, 0) of
        {ok, B} -> 
            case B of 
                %do_recv(Socket,  [Bs, B]);
                _ -> gen_tcp:send(Socket, "Hellllooooooooooo")
            end;
        {error, closed} -> 
            {ok, list_to_binary(Bs)}
    end.

我不知道我在做什么是否正确,例如:我有服务器的控制台,我用server:init(8889) 初始化他,在 cmd 我输入 telnet localhost 8889 然后我按回车它说喂喂喂喂喂。或者我也可以在 Erlang 中使用我的客户端,但关键是如何让服务器通过 telnet 或客户端接口发送连接到他的消息?

【问题讨论】:

    标签: tcp erlang


    【解决方案1】:

    如果我很理解你的意图,这里有一些一般性的提示:

    1. 为了保持服务器“活跃”,接收函数必须是尾递归的。所以基本上这个函数应该:等待一个信号,当它得到一个 - 服务它并再次递归调用自己。要使其停止,只需指定一条特殊消息,该消息将在递归到达函数时停止。非常通用的代码(获取消息并在屏幕上打印相应的响应):

      serveSignal() ->

          receive 
              hello -> io:format("Hello World!"),
                       serveSignal();
              bye   -> io:format("Bye World!"),
                       serveSignal();
              stop  -> {"Server stopped", ok};
              _     -> unknownMessage,
                       serveSignal()
          end.
      
    2. 为了使服务器对不同的请求/用户做出不同的响应,您的服务函数需要接收,例如,带有一些适当参数的元组。例如,让您的一个接收器函数获取信号,确定发送器的 IP,然后将元组 {IP, signal} 发送到另一个函数,该函数将向给定的 IP 发送回复(与信号足够)。所以第二种方法的通用代码可能是这样的:

    receive

        {IP, signalOne} -> replyingFunctionPID ! {IP, responseToSignalOne};
        {IP, signalTwo} -> replyingFunctionPID ! {IP, responseToSignalTwo}
    end
    

    【讨论】:

    • 嗯,这是一个不错的方法,但它不是简单的接收,因为我正在使用 [{active, false}] 选项,并且您可以看到注释行调用了接收函数递归(可以看到最后一个函数do_recv)do_recv(Socket, [Bs, B]);并且不起作用):
    猜你喜欢
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多