Node communication built by Erlang and C

Source: Internet
Author: User
Tags ip number

The communication between Erlang nodes is mainly used for communication between two Erlang nodes. However, Erlang also supports communication with nodes built in Java and even nodes built in C, the previous two methods have been mentioned in my previous articles, so here we will talk about the node communication between Erlang and C.

CNode and erl_interface

To build an Erlang node in C, you must use the erl_interface interface of Erlang. The node established by C is called a cNode. In addition to some basic node connections and message sending and receiving, erl_interface also implements the construction and parsing of Erlang term.

CNode is another c extension Erlang method except NIF, but compared with NIF, this method does not cause Erlang crash, because they communicate through socket at the underlying layer in different processes.

Another problem is that cNode is hidden in the Erlang cluster. Therefore, the node cannot be found using nodes () in Erlang. However, after the node is connected successfully, it can be obtained through nodes (connected.

Communication between cNode and Erlang

The following describes how to use cNode to communicate with Erlang in Windows (Demo download)

I. Preparations
1. Download the Erlang binary installation package. Here r16b02 is used as an example.

2. After installing Erlang, go to the installation directory to get the Erlang header file and static library package:

Erl header file: erl5.10.3 \ Lib \ erl_interface-3.7.14 \ include \

Erl static library: erl5.10.3 \ Lib \ erl_interface-3.7.14 \ Lib, static library here only use ei_md.lib and erl_interface_md.lib

2. Create a C Project

1. Create an empty project named cNode

2. Copy the include folder and Lib folder to the project directory.

3. Modify project properties. Select the Unicode Character Set for the character set.

4. Modify project properties. Add "include" to the include directory of the VC ++ directory, and add "lib" to the library"

5. Add the project file cNode. C and save the following code:

# Include <stdio. h> # include <sys/types. h> # ifdef _ Win32 # DEFINE _ Win32 __# include <winsock2.h> # pragma comment (Lib, "ws2_32.lib") # pragma comment (Lib, "ei_md.lib ") # pragma comment (Lib, "erl_interface_md.lib") # pragma comment (linker, "/nodefaultlib: msvcrtd. lib ") # endif # include" erl_interface.h "# include" EI. H "# define bufsize 1000 # Define Port 8088int Foo (int x) {return x + 1;} int bar (INT y) {return y * 2 ;} Int main (INT argc, char ** argv) {struct in_addr ADDR;/* 32-bit IP number of host */INT port;/* Listen Port Number */INT listen; /* Listen socket */int fd;/* FD to Erlang node */erlconnect conn;/* connection data */INT loop = 1;/* loop flag */INT got; /* result of receive */unsigned char Buf [bufsize];/* buffer for incoming message */erlmessage emsg;/* Incoming message */eterm * fromp, * tuplep, * FNP, * argp, * resp; int res; # ifdef _ Win32 // initialize the Winsock service wsadata; wsastartup (makeword (2, 2), & wsadata ); # endif Port = port; erl_init (null, 0); ADDR. s_addr = inet_addr ("127.0.0.1"); If (erl_connect_xinit ("idril", "cNode", "[email protected]", & ADDR, "secretcookie", 0) =-1) erl_err_quit ("erl_connect_xinit");/* Make a listen socket */If (Listen = my_listen (port) <= 0) erl_err_quit ("my_listen "); If (erl_publish (port) =-1) erl_err_quit ("erl_publish"); If (FD = erl_accept (Listen, & conn) = erl_error) erl_err_quit ("erl_accept"); fprintf (stderr, "connected to % s \ n \ r", Conn. nodename); While (loop) {got = erl_receive_msg (FD, Buf, bufsize, & emsg); If (got = erl_tick) {/* ignore */} else if (got = erl_error) {loop = 0;} else {If (emsg. type = erl_reg_send) {fromp = erl_element (2, emsg. MSG); tuplep = Erl_element (3, emsg. MSG); FNP = erl_element (1, tuplep); argp = erl_element (2, tuplep); If (strncmp (erl_atom_ptr (FNP), "foo", 3) = 0) {res = Foo (erl_int_value (argp);} else if (strncmp (erl_atom_ptr (FNP), "bar", 3) = 0) {res = bar (erl_int_value (argp);} resp = erl_format ("{cNode ,~ I} ", Res); erl_send (FD, fromp, resp); erl_free_term (emsg. from); erl_free_term (emsg. MSG); erl_free_term (fromp); erl_free_term (tuplep); erl_free_term (FNP); erl_free_term (argp); erl_free_term (RESP) ;}}} int my_listen (INT port) {int listen_fd; struct sockaddr_in ADDR; int on = 1; if (listen_fd = socket (af_inet, sock_stream, 0) <0) Return (-1); setsockopt (listen_fd, sol_socket, so_reuseaddr, & on, sizeof (on); memset (void *) & ADDR, 0, (size_t) sizeof (ADDR); ADDR. sin_family = af_inet; ADDR. sin_port = htons (port); ADDR. sin_addr.s_addr = htonl (inaddr_any); If (BIND (listen_fd, (struct sockaddr *) & ADDR, sizeof (ADDR) <0) Return (-1); Listen (listen_fd, 5); Return listen_fd ;}
After compilation, the program cnode.exe will be generated. Start the Erlang EPMD service and then run the program. The reason is that the communication between Erlang nodes depends on an underlying port ing service EPMD. The main function of this module is to provide a mechanism to identify machines by name.

7. Start the Erlang EPMD Service

You can start an Erlang node on the local machine. Erlang automatically starts the EPMD service. This program epmd.exe is also included in demoand can be manually executed.

8. Run the Erlang Node

C:\>erl -name [email protected] -setcookie secretcookie Eshell V5.10.3 (abort with ^G) ([email protected])1> net_kernel:connect(‘[email protected]‘). true ([email protected])2> {any, ‘[email protected]‘} ! {call, self(), {bar, 3}}. {call,<0.36.0>,{bar,3}} ([email protected])3> flush(). Shell got {cnode,6} ok ([email protected]0.0.1)4> {any, ‘[email protected]‘} ! {call, self(), {foo, 3}}. {call,<0.36.0>,{foo,3}} ([email protected])5> flush(). Shell got {cnode,4} ok
Complete demo download: http://download.csdn.net/detail/cwqcwk1/8126053

Why can't the demo be compiled or cannot be compiled?

I have previously written an example of nif. Some netizens said that the demo could not run. Here we will summarize the situation:

1. the Erlang version of the demo is r16b02. You must use this version of Erlang; otherwise, problems may occur. Download Page

2. My compiler is vs2010 and must be installed with a compiler later than vs2010. To run this demo, you must install the vc2010 Runtime Library.

3. When the epmdservice is not started, demohas epmd.exe, And you can double-click it. Or start an Erlang node on the local machine. Erlang will automatically start the service. '

4. Reasons why other Erlang nodes cannot communicate with each other, as well as Cookie and name issues. For details, refer to this article.

The above is an example of using cNode as a server node. The code for using cNode as a client node is also posted below:

int main(int argc, char **argv) {int fd;                                  /* fd to Erlang node */int loop = 1;                            /* Loop flag */int got;                                 /* Result of receive */unsigned char buf[BUFSIZE];              /* Buffer for incoming message */ErlMessage emsg;                         /* Incoming message */ETERM *fromp, *tuplep, *fnp, *argp, *resp;int res;  erl_init(NULL, 0);if (erl_connect_init(1, "secretcookie", 0) == -1)erl_err_quit("erl_connect_init");if ((fd = erl_connect("[email protected]")) < 0)erl_err_quit("erl_connect");fprintf(stderr, "Connected to [email protected]\n\r");while (loop) {got = erl_receive_msg(fd, buf, BUFSIZE, &emsg);if (got == ERL_TICK) {/* ignore */} else if (got == ERL_ERROR) {loop = 0;} else {if (emsg.type == ERL_REG_SEND) {fromp = erl_element(2, emsg.msg);tuplep = erl_element(3, emsg.msg);fnp = erl_element(1, tuplep);argp = erl_element(2, tuplep);if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) {res = foo(ERL_INT_VALUE(argp));} else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) {res = bar(ERL_INT_VALUE(argp));}resp = erl_format("{cnode, ~i}", res);erl_send(fd, fromp, resp);erl_free_term(emsg.from); erl_free_term(emsg.msg);erl_free_term(fromp); erl_free_term(tuplep);erl_free_term(fnp); erl_free_term(argp);erl_free_term(resp);}}}}

The code is compiled by referring to the above method.

Finally, if you have any questions about Erlang or are interested in some technologies, you can reply to me. I will find time to study and share or discuss it.


Additional reading:

Node communication between Erlang and Java

Erlang node communication example and Problem Analysis

Erlang communicates with virtual machine nodes in Windows

Using NIF to extend Erlang in Windows


Reference: http://blog.csdn.net/mycwq/article/details/40836273

Http://www.erlang.org/doc/tutorial/cnode.html

Node communication built by Erlang and C

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.