在不同终端窗口上运行Erlang程序时出现异常

在不同终端窗口上运行Erlang程序时出现异常,erlang,distributed,distributed-computing,Erlang,Distributed,Distributed Computing,我正在用Erlang开发一个简单的框架来处理基于2人回合的游戏。代码如下: -module(game). -export([start_server/0,generate_server/0,add_player/0,remove_player/0]). generate_server() -> Table_num = 0, Player_num = 0, io:format("Server generated...~n", []), io:format("The current num

我正在用Erlang开发一个简单的框架来处理基于2人回合的游戏。代码如下:

-module(game).
-export([start_server/0,generate_server/0,add_player/0,remove_player/0]).


generate_server() ->
Table_num = 0,
Player_num = 0,
io:format("Server generated...~n", []),
io:format("The current number of tables is ~w~n", [Table_num]),
io:format("The current number of players is ~w~n", [Player_num]),
receive
    login ->
        io:format("A new player has connected!~n", []),
        New = Player_num + 1,
        io:format("The current number of players is ~w~n", [New]);
    logout ->
        io:format("You have beeen succesfully disconnected~n", [])
end.



start_server() ->
    io:format("Welcome player!~nInitializing game...~n", []),
    io:format("Generating server...~n", []),
    register(server,spawn(game, generate_server, [])).


add_player() ->
    server ! login.


remove_player() ->
    server ! logout.
运行此代码时存在两个主要问题:

  • 当我执行add_player()然后执行remove_player()时,第二个函数崩溃,出现异常
  • 如果我在一个终端窗口上启动程序,然后在另一个终端窗口上执行add_player(),我会得到一个错误。我应该怎么做才能在多个终端窗口上运行它
  • 任何帮助都将不胜感激。

    1/ 服务器中没有循环。当您启动它时,在一些打印之后,它会等待接收语句

    收到登录消息后,执行操作,服务器代码完成;该进程已死亡,并且未注册。所有变量消失,虚拟机清理内存

    因此,稍后,任何向服务器发送消息的进程都将崩溃,因为您使用的是一个不再注册的名称

    要使其工作,您应该保留一个已连接玩家的列表(例如在列表中),并使用此列表作为参数调用服务器循环

    generate_server(Tlist,Plist) ->
    io:format("The current number of tables is ~w~n", [length(Tlist)]),
    io:format("The current number of players is ~w~n", [length(Plist)]),
    receive
        {login,Name} ->
            io:format("A new player ~p has connected!~n", [Name]),
            generate_server(Tlist,[Name|Plist]);
        {logout,Name} ->
            io:format("You have beeen succesfully disconnected~n", []),
            generate_server(Tlist,lists:delete(Name,Plist))
    end.
    
    生成_服务器的调用由

    register(server,spawn(game, generate_server, [[],[]]))
    
    二,/ 为了在2个不同节点之间使用erlang消息,您需要:

    • 共享同一个erlang coockie
    • 发现节点(例如使用netadm)
    • 获取服务器pid或使用golbal注册名称
    参见第1页的示例/ 服务器中没有循环。当您启动它时,在一些打印之后,它会等待接收语句

    收到登录消息后,执行操作,服务器代码完成;该进程已死亡,并且未注册。所有变量消失,虚拟机清理内存

    因此,稍后,任何向服务器发送消息的进程都将崩溃,因为您使用的是一个不再注册的名称

    要使其工作,您应该保留一个已连接玩家的列表(例如在列表中),并使用此列表作为参数调用服务器循环

    generate_server(Tlist,Plist) ->
    io:format("The current number of tables is ~w~n", [length(Tlist)]),
    io:format("The current number of players is ~w~n", [length(Plist)]),
    receive
        {login,Name} ->
            io:format("A new player ~p has connected!~n", [Name]),
            generate_server(Tlist,[Name|Plist]);
        {logout,Name} ->
            io:format("You have beeen succesfully disconnected~n", []),
            generate_server(Tlist,lists:delete(Name,Plist))
    end.
    
    生成_服务器的调用由

    register(server,spawn(game, generate_server, [[],[]]))
    
    二,/ 为了在2个不同节点之间使用erlang消息,您需要:

    • 共享同一个erlang coockie
    • 发现节点(例如使用netadm)
    • 获取服务器pid或使用golbal注册名称

    请参见

    中的示例,您遗漏了服务器的
    循环体。您的程序崩溃,因为服务器只收到一条消息并退出。考虑下面的服务器的另一个版本:
    generate_server() ->
        Table_num = 0,
        Player_num = 0,
        io:format("Server generated...~n", []),
        io:format("The current number of tables is ~w~n", [Table_num]),
        io:format("The current number of players is ~w~n", [Player_num]),
        loop([]).
    loop(Players)-> receive {From,{login,PlayerId}} -> io:format("A new player has connected!~n", []), io:format("The current number of players is ~w~n", [New]), NewPlayers = case lists:member(PlayerId,Players) of true -> From ! {login_failed,exists}, Players; false -> From ! {login_success,true}, [PlayerId|Players] end, loop(NewPlayers); {From,{logout,PlayerId}} -> NewPlayers = case lists:member(PlayerId,Players) of true -> From ! {logout,ok}, Players -- [PlayerId]; false -> From ! {logout,failed}, Players end,
    loop(NewPlayers); _ -> loop(Players) end. 生成\u服务器()-> 表_num=0, Player_num=0, io:格式(“服务器生成的…~n”,[]), io:format(“当前表数为~w~n”,[Table_num]), io:format(“当前玩家数量为~w~n”,[Player_num]), 循环([])。
    循环(玩家)-> 接收 {From,{login,PlayerId}}-> io:format(“新玩家已连接!~n”,[]), io:format(“当前玩家数量为~w~n”,[New]), 新玩家=案例列表:成员(玩家ID,玩家) 正确-> 从…起{登录失败,存在}, 球员; 错误-> 从…起{login_success,true}, [玩家ID |玩家] 完,, 循环(新玩家); {From,{注销,PlayerId}}-> 新玩家=案例列表:成员(玩家ID,玩家) 正确-> 从…起{退出,好}, 玩家--[玩家ID]; 错误-> 从…起{注销,失败}, 球员 结束,
    循环(新玩家); _->循环(玩家) 结束。
    那里看起来好多了

    您错过了服务器的
    循环体。您的程序崩溃,因为服务器只收到一条消息并退出。考虑下面的服务器的另一个版本:
    generate_server() ->
        Table_num = 0,
        Player_num = 0,
        io:format("Server generated...~n", []),
        io:format("The current number of tables is ~w~n", [Table_num]),
        io:format("The current number of players is ~w~n", [Player_num]),
        loop([]).
    loop(Players)-> receive {From,{login,PlayerId}} -> io:format("A new player has connected!~n", []), io:format("The current number of players is ~w~n", [New]), NewPlayers = case lists:member(PlayerId,Players) of true -> From ! {login_failed,exists}, Players; false -> From ! {login_success,true}, [PlayerId|Players] end, loop(NewPlayers); {From,{logout,PlayerId}} -> NewPlayers = case lists:member(PlayerId,Players) of true -> From ! {logout,ok}, Players -- [PlayerId]; false -> From ! {logout,failed}, Players end,
    loop(NewPlayers); _ -> loop(Players) end. 生成\u服务器()-> 表_num=0, Player_num=0, io:格式(“服务器生成的…~n”,[]), io:format(“当前表数为~w~n”,[Table_num]), io:format(“当前玩家数量为~w~n”,[Player_num]), 循环([])。
    循环(玩家)-> 接收 {From,{login,PlayerId}}-> io:format(“新玩家已连接!~n”,[]), io:format(“当前玩家数量为~w~n”,[New]), 新玩家=案例列表:成员(玩家ID,玩家) 正确-> 从…起{登录失败,存在}, 球员; 错误-> 从…起{login_success,true}, [玩家ID |玩家] 完,, 循环(新玩家); {From,{注销,PlayerId}}-> 新玩家=案例列表:成员(玩家ID,玩家) 正确-> 从…起{退出,好}, 玩家--[玩家ID]; 错误-> 从…起{注销,失败}, 球员 结束,
    循环(新玩家); _->循环(玩家) 结束。
    那里看起来好多了

    非常感谢你的帮助:)我会有更多的问题:p非常感谢你的帮助:)我会有更多的问题:p