Functional programming 在Erlang中将客户端添加到列表

Functional programming 在Erlang中将客户端添加到列表,functional-programming,erlang,tuples,Functional Programming,Erlang,Tuples,因此,我正在编写一个客户端可以连接的基本服务器。我正在用telnet进行测试,但我的问题是如何将客户端存储在列表中,以便打印出连接到服务器的用户。我曾尝试在存储客户机的列表上使用++运算符,但我一直遇到一个进程错误 以下是我目前的代码: cell_process()-> io:fwrite("In cell~n"), {ok,Listening_socket} = gen_tcp:listen(21,

因此,我正在编写一个客户端可以连接的基本服务器。我正在用telnet进行测试,但我的问题是如何将客户端存储在列表中,以便打印出连接到服务器的用户。我曾尝试在存储客户机的列表上使用++运算符,但我一直遇到一个进程错误

以下是我目前的代码:

cell_process()->
    io:fwrite("In cell~n"),
    {ok,Listening_socket} = gen_tcp:listen(21,
                                           [binary,
                                            {backlog,5},
                                            {active,false},
                                            {packet,line}]),
    loop(Listening_socket).

loop(Listening_socket)->
    case gen_tcp:accept(Listening_socket) of
        {ok,Client_socket} ->

            gen_tcp:send(Client_socket, "Hello, what is your name?"),
            {_,Name} = gen_tcp:recv(Client_socket,0),
            gen_tcp:send(Client_socket, "Hello, "),
            gen_tcp:send(Client_socket, Name),
            io:fwrite([Name]),
            spawn(fun()-> client_loop(Client_socket) end),
            loop(Listening_socket);

        {error,Why}->io:fwrite("Error: "),
                     io:fwrite([Why])
    end.

client_loop(Client_socket)->
    case gen_tcp:recv(Client_socket,0) of
        {ok,Message}-> gen_tcp:send(Client_socket,Message),
                       %% code not yet implemented here
                       client_loop(Client_socket);

        {error,Why}-> io:fwrite("Error: ~s~n",[Why]),
                      gen_tcp:close(Client_socket)
    end.

非常感谢您的阅读。要跟踪已连接的客户端,您必须向循环函数添加一个变量,并按照您的建议将任何相关信息存储在客户端列表中

cell_process()->
    io:fwrite("In cell~n"),
    {ok,Listening_socket} = gen_tcp:listen(21,
                                           [binary,
                                            {backlog,5},
                                            {active,false},
                                            {packet,line}]),
    loop(Listening_socket,[]). %% initial Clients list is empty

loop(Listening_socket,Clients)->
    case gen_tcp:accept(Listening_socket) of
        {ok,Client_socket} ->

            gen_tcp:send(Client_socket, "Hello, what is your name?"),
            {_,Name} = gen_tcp:recv(Client_socket,0),
            gen_tcp:send(Client_socket, "Hello, "),
            gen_tcp:send(Client_socket, Name),
            io:fwrite([Name]),
            Pid = spawn(fun()-> client_loop(Client_socket) end),
            loop(Listening_socket,[{Pid,Client_socket,Name}|Clients]);
%%将新客户添加到列表中,但请查看我的评论

        {error,Why}->io:fwrite("Error: "),
                     io:fwrite([Why])
    end.

client_loop(Client_socket)->
    case gen_tcp:recv(Client_socket,0) of
        {ok,Message}-> gen_tcp:send(Client_socket,Message),
                       %% code not yet implemented here
                       client_loop(Client_socket);

        {error,Why}-> io:fwrite("Error: ~s~n",[Why]),
                      gen_tcp:close(Client_socket)
    end.
注释:它不是存储客户机列表的正确位置,因为您必须使用链接或监视器来管理即将死亡的客户机,因此您需要一个与套接字侦听不兼容的接收块。因此,我认为您应该添加一个服务器来管理此列表,该服务器的角色是在每次启动新客户机时侦听发送的消息,监视客户机,在管理员想要了解客户机列表时回答管理员…

这里有一个建议:

loop(Listening_socket, ClientList)->
    case gen_tcp:accept(Listening_socket) of
        {ok,Client_socket} ->
            gen_tcp:send(Client_socket, "Hello, what is your name?"),
            {_,Name} = gen_tcp:recv(Client_socket,0),
            gen_tcp:send(Client_socket, "Hello, "),
            gen_tcp:send(Client_socket, Name),
            io:fwrite([Name]),
            spawn(fun()-> client_loop(Client_socket) end),
            loop(Listening_socket, [Client_socket | ClientList]);

        {error,Why}->io:fwrite("Error: "),
                     io:fwrite([Why])
    end.

一个更好的解决方案是有一个
状态
记录,在其中存储所有需要的变量(在本例中,是侦听套接字和ClientList),并循环使用该
状态

这非常有效,谢谢!我现在遇到的另一个问题是如何将客户机列表打印到shell中,我尝试了io:fwrite,但这会导致进程崩溃。