1
votes

I newbie in erlang. I cant understand why my program dont work. Help me please.

server() ->
        io:format("server ~n"),
        register( doServer, Pid = spawn(node(), ?MODULE, doServer,[[]])),
        io:format("server ~p ~n", [registered()]).

client() ->
        io:format("client ~p ~n", [registered()]),
        spawn_clients(1).

Server do register(atom, PID)

register( doServer, Pid = spawn(node(), ?MODULE, doServer,[[]])),

erlc smplMessenger.erl ;  echo " ****** RUN *******"; \
erl -noshell -sname p1 +v setcookie k1 -s smplMessenger server 

 ****** RUN *******
server 
server [code_server,erl_prim_loader,application_controller,kernel_safe_sup,
        standard_error_sup,inet_db,init,erts_code_purger,user,***doServer***,
        error_logger,rex,kernel_sup,erl_signal_server,global_name_server,
        standard_error,global_group,file_server_2] 
Start server 

In print "registered()." I can see alias "doServer"

But client cant see alias "doServer" and its PID

erl -noshell setcookie k1 -sname p2  -s smplMessenger client 
Erlang/OTP 20 [erts-9.3] [source] [smp:2:2] [ds:2:2:10] [async-threads:10] [hipe] [kernel-poll:false]

client [code_server,erl_prim_loader,application_controller,erl_epmd,auth,
        standard_error_sup,net_kernel,inet_db,init,erts_code_purger,user,
        error_logger,rex,net_sup,kernel_sup,user_drv,kernel_safe_sup,
        erl_signal_server,global_name_server,standard_error,global_group,
        file_server_2] 
[Client <0.5.0>] node 1 spawned 
All client spawned
[Client <0.67.0> 1] Start client with serv pid undefined. Im alive 

=ERROR REPORT==== 31-May-2018::21:52:07 ===
Error in process <0.67.0> on node p2@station with exit value:
{badarg,[{smplMessenger,doClient,1,[{file,"smplMessenger.erl"},{line,121}]}]}

line 121 is

118: doClient(Name) ->
119:        io:format("[Client ~p ~p] Start client with serv pid ~p. Im alive ~n",
120:                        [self(), Name, whereis(doServer)]),
121:        doServer ! {isAlive, self(), Name},
121:
122:        clientRecv(Name),
123:
124:        io:format("[Client ~p ~p] FINISH CLIENT ~n",
125:                        [self(), Name]).

I run two nodes from one computer (Cooke in two nodes is equal).

epmd see client and server processes.

Node 1 and node 2 can ping both of.

netstat -tuwpln
Proto Recv-Q Send-Q Local Address Foreign Address State       PID/Program name
tcp        0      0 0.0.0.0:4369            0.0.0.0:*               LISTEN      1408/epmd
tcp        0      0 0.0.0.0:36499           0.0.0.0:*               LISTEN      3008/beam.smp
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:33865           0.0.0.0:*               LISTEN      3047/beam.smp
tcp6       0      0 :::4369                 :::*                    LISTEN      1408/epmd
tcp7       0      0 ::1:631                 :::*                    LISTEN      -

Where I wrong ? Help me.

I change register to global but client process cant see server (doServer) anything.

server() ->
        io:format("server ~n"),
        global:register_name( doServer, spawn(node(), ?MODULE, doServer,[[]])),
        io:format("server ~p ~n", [global:registered_names()]).


client() ->
        io:format("[Client ~p ] ~p ~n",
                        [self(), global:whereis_name(doServer)]),
        io:format("client ~p ~n", [global:registered_names()]).

erlc smplMessenger.erl ;  echo " ****** RUN *******"; erl -noshell -sname p1 -v -setcookie k1 -s smplMessenger server
 ****** RUN *******
server 
Start server 
server [doServer]

erlc smplMessenger.erl ;  echo " ****** RUN *******"; erl -noshell -sname p2 -v -setcookie k1 -s smplMessenger client

****** RUN *******
[Client <0.5.0> ] undefined 
client [] 
1

1 Answers

1
votes

function registered() ( It's actually erlang:registered/0 MFA. MFA stands for Module, Function, Arity./0 is arity and means it accepts 0 arguments) shows registered processes and ports which are registered using erlang:register/2. erlang:register/2 registers a name for a process or port locally then works per node and only for that node. This means node p1 has its own registered processes and does not know about registered processes of other nodes. Also Node p2 does not know about registered process of other nodes.
I recommed to use global module to register a name for a process in a system consisting many Erlang nodes.
For above example you need functions global:register_name/2 and global:registered_names/0. Also you should connect second started node to first node before these operations.