所以我正在编写客户端可以连接的基本服务器。我正在用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.
感谢阅读,非常感谢任何帮助。
答案 0 :(得分:1)
要保留已连接客户端的痕迹,您必须向循环函数添加变量,并按照建议将任何相关信息存储在客户端列表中。
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.
注释:它不是存储客户端列表的正确位置,因为您必须使用链接或监视器来管理正在死亡的客户端,因此您需要一个与套接字侦听不兼容的接收块。所以我认为你应该添加一个服务器来管理这个列表,哪个角色是监听每次启动新客户端时发送的消息,监控客户端,当他想知道客户端列表时回答管理员... < / p>
答案 1 :(得分:1)
这是一个建议:
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.
更好的解决方案是使用state
记录存储所需的所有变量(在本例中为Listening_socket和ClientList)并使用state
循环。