1

所以我正在编写一个客户端可以连接的基本服务器。我正在使用 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.

任何帮助将不胜感激,感谢阅读。

4

2 回答 2

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.

评论:这不是存储客户端列表的正确位置,因为您将不得不使用链接或监视器来管理正在死亡的客户端,因此您需要一个接收块,与套接字侦听不兼容。所以我认为你应该添加一个服务器来管理这个列表,它的作用是监听每次启动新客户端时发送的消息,监控客户端,当他想知道客户端列表时回复管理员......

于 2013-08-07T16:37:30.720 回答
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.

于 2013-08-07T16:37:56.360 回答