Functional programming 在Erlang中将客户端添加到列表
因此,我正在编写一个客户端可以连接的基本服务器。我正在用telnet进行测试,但我的问题是如何将客户端存储在列表中,以便打印出连接到服务器的用户。我曾尝试在存储客户机的列表上使用++运算符,但我一直遇到一个进程错误 以下是我目前的代码: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,
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,但这会导致进程崩溃。