erlang-记录与宏
大程序分到多个文件中
mess_config.hrl         配置所需数据头文件
mess_interface.hrl      客户端与 messager 之间的接口定义
user_interface.erl      用户接口函数
mess_client.erl         messager 系统客户端的函数
mess_server.erl         messager 服务端的函数
mess_config.hrl
%%%----FILE mess_config.hrl----
%%% Configure the location of the server node,
-define(server_node, messenger@super).
%%%----END FILE----
mess_interface.hr
%%%----FILE mess_interface.hrl----
%%%Message interface between client and server and client shell for
%%% messenger program 
%%%Messages from Client to server received in server/1 function.
-record(logon,{client_pid, username}).
-record(message,{client_pid, to_name, message}).
%%% {'EXIT', ClientPid, Reason}  (client terminated or unreachable.
%%% Messages from Server to Client, received in await_result/0 function 
-record(abort_client,{message}).
%%% Messages are: user_exists_at_other_node, 
%%%               you_are_not_logged_on
-record(server_reply,{message}).
%%% Messages are: logged_on
%%%               receiver_not_found
%%%               sent  (Message has been sent (no guarantee)
%%% Messages from Server to Client received in client/1 function
-record(message_from,{from_name, message}).
%%% Messages from shell to Client received in client/1 function
%%% spawn(mess_client, client, [server_node(), Name])
-record(message_to,{to_name, message}).
%%% logoff
%%%----END FILE----
user_interface.erl
%%%----FILE mess_interface.hrl----
%%% Message interface between client and server and client shell for
%%% messenger program 
%%%Messages from Client to server received in server/1 function.
-record(logon,{client_pid, username}).
-record(message,{client_pid, to_name, message}).
%%% {'EXIT', ClientPid, Reason}  (client terminated or unreachable.
%%% Messages from Server to Client, received in await_result/0 function 
-record(abort_client,{message}).
%%% Messages are: user_exists_at_other_node, 
%%%               you_are_not_logged_on
-record(server_reply,{message}).
%%% Messages are: logged_on
%%%               receiver_not_found
%%%               sent  (Message has been sent (no guarantee)
%%% Messages from Server to Client received in client/1 function
-record(message_from,{from_name, message}).
%%% Messages from shell to Client received in client/1 function
%%% spawn(mess_client, client, [server_node(), Name])
-record(message_to,{to_name, message}).
%%% logoff
%%%----END FILE----
mess_client.erl
%%%----FILE mess_client.erl----
%%% The client process which runs on each user node
-module(mess_client).
-export([client/2]).
-include("mess_interface.hrl").
client(Server_Node, Name) ->
    {messenger, Server_Node} ! #logon{client_pid=self(), username=Name},
    await_result(),
    client(Server_Node).
client(Server_Node) ->
    receive
        logoff ->
            exit(normal);
        #message_to{to_name=ToName, message=Message} ->
            {messenger, Server_Node} ! 
                #message{client_pid=self(), to_name=ToName, message=Message},
            await_result();
        {message_from, FromName, Message} ->
            io:format("Message from ~p: ~p~n", [FromName, Message])
    end,
    client(Server_Node).
%%% wait for a response from the server
await_result() ->
    receive
        #abort_client{message=Why} ->
            io:format("~p~n", [Why]),
            exit(normal);
        #server_reply{message=What} ->
            io:format("~p~n", [What])
    after 5000 ->
            io:format("No response from server~n", []),
            exit(timeout)
    end.
%%%----END FILE---
mess_server.erl
%%%----FILE mess_server.erl----
%%% This is the server process of the messenger service
-module(mess_server).
-export([start_server/0, server/0]).
-include("mess_interface.hrl").
server() ->
    process_flag(trap_exit, true),
    server([]).
%%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...]
server(User_List) ->
    io:format("User list = ~p~n", [User_List]),
    receive
        #logon{client_pid=From, username=Name} ->
            New_User_List = server_logon(From, Name, User_List),
            server(New_User_List);
        {'EXIT', From, _} ->
            New_User_List = server_logoff(From, User_List),
            server(New_User_List);
        #message{client_pid=From, to_name=To, message=Message} ->
            server_transfer(From, To, Message, User_List),
            server(User_List)
    end.
%%% Start the server
start_server() ->
    register(messenger, spawn(?MODULE, server, [])).
%%% Server adds a new user to the user list
server_logon(From, Name, User_List) ->
    %% check if logged on anywhere else
    case lists:keymember(Name, 2, User_List) of
        true ->
            From ! #abort_client{message=user_exists_at_other_node},
            User_List;
        false ->
            From ! #server_reply{message=logged_on},
            link(From),
            [{From, Name} | User_List]        %add user to the list
    end.
%%% Server deletes a user from the user list
server_logoff(From, User_List) ->
    lists:keydelete(From, 1, User_List).
%%% Server transfers a message between user
server_transfer(From, To, Message, User_List) ->
    %% check that the user is logged on and who he is
    case lists:keysearch(From, 1, User_List) of
        false ->
            From ! #abort_client{message=you_are_not_logged_on};
        {value, {_, Name}} ->
            server_transfer(From, Name, To, Message, User_List)
    end.
%%% If the user exists, send the message
server_transfer(From, Name, To, Message, User_List) ->
    %% Find the receiver and send the message
    case lists:keysearch(To, 2, User_List) of
        false ->
            From ! #server_reply{message=receiver_not_found};
        {value, {ToPid, To}} ->
            ToPid ! #message_from{from_name=Name, message=Message}, 
            From !  #server_reply{message=sent} 
    end.
%%%----END FILE---
头文件
在其他文件中引用
-include("mess_interface.hrl").
记录
定义
-record(name_of_record,{field_name1, field_name2, field_name3, ......}).
等价形式
-record(message_to,{to_name, message}).
{message_to, To_Name, Message}
创建记录
#message_to{message="hello", to_name=fred)
创建的记录如下
{message_to, fred, "hello"}
使用记录与创建一样
#message_to{to_name=ToName, message=Message} ->
等价于
{message_to, ToName, Message}
宏
-define(server_node, messenger@super).
这样引用后,每个server_node都被替换为messenger@super
宏还被用于生成服务端进程
spawn(?MODULE, server, [])
这是一个系统定义的宏,?MODULE被替换为当前模块名
 
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号