1

I'm trying to use distributing programming in Erlang.

But I had a problem, I can't communicate two Erlang's nodes to communicate.

I tried to put the same atom in the "Magical cookies", but it didn't work.

I tried to use command net:ping(node), but reponse was pang (didn't reconigze another node), or used nodes(), to see if my first node see the second node, but it didn't work again.

The first and second node is CentOS in VMWare, using bridge connection in network adaptor.

I entered command ping outside Erlang between VM's and they reconigze each one.

I start the first node, but the second node open process, but can't find the node pong.

(pong@localhost)8> tut17:start_pong().
true


(ping@localhost)5> c(tut17).
{ok,tut17}
(ping@localhost)6> tut17:start_ping(pong@localhost).
<0.55.0>

Thank you!

  • 1
    You're going to need to provide some code and context for what you did to get some help. – Suever Mar 03 '16 at 04:17
  • did you check the firewall configuration and the router if any? – Pascal Mar 03 '16 at 10:51
  • can you post `epdm -names` from both nodes? – Greg Mar 03 '16 at 15:44
  • Host 1 `epmd: up and running on port 4369 with data: name ping at port 33880` Host 2 `epmd: up and running on port 4369 with data: name pong at port 59495` – Danilo Avilez Mar 03 '16 at 18:27
  • And what does `node().` return from the Erlang shell on both nodes? – Greg Mar 03 '16 at 18:37
  • One more way is to kill epmd on both nodes and start it in debug mode, e.g.: `epmd -d`. It will then print debug messages when you try to ping the other node. – Greg Mar 03 '16 at 18:40
  • Host 1 `ping@host1` Host 2 `pong@host2`. I'm using command `erl -sname` to give name to nodes. I will try kill them and start debug. – Danilo Avilez Mar 03 '16 at 18:50
  • I tested again, I forget to put the same atom in cookie. It WORKS. Thank you, everybody. Mainly, Amiramax being patient. – Danilo Avilez Mar 03 '16 at 18:59
  • Good job and you are welcome, I hope you will persist with learning Erlang :) – Greg Mar 03 '16 at 19:05

2 Answers2

2

A similar question here.

The distribution is provided by a daemon called Erlang Port Mapper Daemon. By default it listens on port 4369 so you need to make sure that that port is opened between the nodes. Additionally, each started Erlang VM opens an additional port to communicate with other VMs. You can see those ports with epmd -names:

g@someserv1:~ % epmd -names
epmd: up and running on port 4369 with data:
name hbd at port 22200

You can check if the port is opened by doing telnet to it, e.g.:

g@someserv1:~ % telnet 127.0.0.1 22200
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
^]
Connection closed by foreign host.

You can change the port to the port you want to check, e.g. 4369, and also the IP to the desired IP. Doing ping is not enough because it uses its own ICMP protocol which is different that TCP used by the Erlang distribution to communicate, e.g. ICMP may be allowed but TCP may be blocked.

Edit:

Please follow this guide Distributed Erlang to start an Erlang VM in distributed mode. Then you can use net_adm:ping/1 to connect to it from another node, e.g.:

(hbd@someserv1.somehost.com)17> net_adm:ping('hbd@someserv2.somehost.com').
pong

Only then epmd -names will show the started Erlang VM on the list.

Edit2:

Assume that there are tho hosts, A and B. Each one runs one Erlang VM. epmd -names run on each host shows for example:

Host A:

epmd: up and running on port 4369 with data:
name servA at port 22200

Host B:

epmd: up and running on port 4369 with data:
name servB at port 22300

You need to be able to do:

On Host A:

telnet HostB 4369
telent HostB 22300

On Host B:

telnet HostA 4369
telnet HostA 22200

where HostA and HostB are those hosts' IP addresses (.e.g HostA is IP of Host A, HostB is IP of Host B).

If the telnet works correctly then you should be able to do net_adm:ping/1 from one host to the other, e.g. on Host A you would ping the name of Host B. The name is what the command node(). returns.

Community
  • 1
  • 1
Greg
  • 8,230
  • 5
  • 38
  • 53
  • I edited the answer to add info how to start the VM node properly. `epmd -names` doesn't show the VM unless it knows about it, e.g. the VM is started and can be connected to. Please read the guide to learn how the distribution work, in short, the Erlang VM tries to communicate with `epmd` to register in it and to discover other nodes. Then it creates a new port for each VM that it could successfully connect to through `epmd`. – Greg Mar 03 '16 at 12:57
  • Yes, I followed this guide before, but it didn't work. `[erlang@localhost ~]$ epmd -names epmd: up and running on port 4369 with data:` I have only one port 4369. I set my cookie to the same atom, but my nodes don't connect. – Danilo Avilez Mar 03 '16 at 13:28
  • You can't have more than one port 4369. `epmd` is running on 4369 and each newly started VM will have its own port. How did you start your VM and parameters did you use when starting your VM? What do you get when you do `node().` in the Erlang shell? – Greg Mar 03 '16 at 14:51
  • Sorry, Amiramix. I tried at the same host and it works, but for different hosts (Like 2 CentOS in VMWare). I think I have to do something different. Thank you for help me! – Danilo Avilez Mar 03 '16 at 15:12
  • One step at a time. You need to establish if epmd can communicate between those hosts. You need to 1. Establish on which port each Erlang VM listens for connections from other Erlang VMs using the command `epmd -names`. 2. Establish if you can telnet to that port from the other host. I will add an edit to show you what I mean. – Greg Mar 03 '16 at 15:36
  • Amiramix, I did it. Telnet is working for both hosts! – Danilo Avilez Mar 03 '16 at 18:28
  • You mean telnet from Host 1 to Host 2 port 59495 works (and vice versa)? – Greg Mar 03 '16 at 18:38
1

You need to make sure you have a node name for your nodes, or they won't be available to connect with. E.g.:

erl -sname somenode@node1

If you're using separate hosts, then you need to make sure that the node names are resolvable to ip addresses somehow. An easy to way to do this is using /etc/hosts.

# Append a similar line to the /etc/hosts file
10.10.10.10 node1

For more helpful answers, you should post what you see in your terminal when you try this.


EDIT

It looks like your shell is auto picking "localhost" as the node name. You can't send messages to another host with the address "localhost". When specifying the name on the shell, try using the @ syntax to specify the node name as well:

# On host 1:
erl -sname ping@host1

# On host 2
erl -sname pong@host2

Then edit the host file so host1 and host2 will resolve to the right IP.

kjw0188
  • 3,625
  • 16
  • 28
  • I edited my question, that I'm trying use tutorial ping pong from Erlang quickstart. Node pong start successfully, but node ping can't communicate with Pong node. – Danilo Avilez Mar 03 '16 at 14:48