Sophie

Sophie

distrib > Fedora > 17 > i386 > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 135

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../otp_doc.css" type="text/css">
<title>Erlang -- C Nodes</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="../pdf/otp-system-documentation-5.9.3.1.pdf">PDF</a><br><a href="../index.html">Top</a></small><p><strong>Interoperability Tutorial</strong><br><strong>User's Guide</strong><br><small>Version 5.9.3.1</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../js/flipmenu">
<li id="no" title="Introduction" expanded="false">Introduction<ul>
<li><a href="introduction.html">
              Top of chapter
            </a></li>
<li title="Purpose"><a href="introduction.html#id60800">Purpose</a></li>
<li title="Prerequisites"><a href="introduction.html#id60757">Prerequisites</a></li>
</ul>
</li>
<li id="no" title="Overview" expanded="false">Overview<ul>
<li><a href="overview.html">
              Top of chapter
            </a></li>
<li title="Built-In Mechanisms"><a href="overview.html#id62194">Built-In Mechanisms</a></li>
<li title="C and Java Libraries"><a href="overview.html#id60915">C and Java Libraries</a></li>
<li title="Standard Protocols"><a href="overview.html#id62774">Standard Protocols</a></li>
<li title="IC"><a href="overview.html#id61047">IC</a></li>
<li title="Old Applications"><a href="overview.html#id62555">Old Applications</a></li>
</ul>
</li>
<li id="no" title="Problem Example" expanded="false">Problem Example<ul>
<li><a href="example.html">
              Top of chapter
            </a></li>
<li title="Description"><a href="example.html#id63860">Description</a></li>
</ul>
</li>
<li id="no" title="Ports" expanded="false">Ports<ul>
<li><a href="c_port.html">
              Top of chapter
            </a></li>
<li title="Erlang Program"><a href="c_port.html#id58262">Erlang Program</a></li>
<li title="C Program"><a href="c_port.html#id62416">C Program</a></li>
<li title="Running the Example"><a href="c_port.html#id63496">Running the Example</a></li>
</ul>
</li>
<li id="no" title="Erl_Interface" expanded="false">Erl_Interface<ul>
<li><a href="erl_interface.html">
              Top of chapter
            </a></li>
<li title="Erlang Program"><a href="erl_interface.html#id63174">Erlang Program</a></li>
<li title="C Program"><a href="erl_interface.html#id63282">C Program</a></li>
<li title="Running the Example"><a href="erl_interface.html#id61784">Running the Example</a></li>
</ul>
</li>
<li id="no" title="Port drivers" expanded="false">Port drivers<ul>
<li><a href="c_portdriver.html">
              Top of chapter
            </a></li>
<li title="Port Drivers"><a href="c_portdriver.html#id61981">Port Drivers</a></li>
<li title="Erlang Program"><a href="c_portdriver.html#id62001">Erlang Program</a></li>
<li title="C Driver"><a href="c_portdriver.html#id62119">C Driver</a></li>
<li title="Running the Example"><a href="c_portdriver.html#id63970">Running the Example</a></li>
</ul>
</li>
<li id="loadscrollpos" title="C Nodes" expanded="true">C Nodes<ul>
<li><a href="cnode.html">
              Top of chapter
            </a></li>
<li title="Erlang Program"><a href="cnode.html#id64088">Erlang Program</a></li>
<li title="C Program"><a href="cnode.html#id64168">C Program</a></li>
<li title="Running the Example"><a href="cnode.html#id64499">Running the Example</a></li>
</ul>
</li>
<li id="no" title="NIFs" expanded="false">NIFs<ul>
<li><a href="nif.html">
              Top of chapter
            </a></li>
<li title="NIFs"><a href="nif.html#id64799">NIFs</a></li>
<li title="Erlang Program"><a href="nif.html#id64820">Erlang Program</a></li>
<li title="NIF library code"><a href="nif.html#id64884">NIF library code</a></li>
<li title="Running the Example"><a href="nif.html#id64985">Running the Example</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>7 C Nodes</h1>
  
  <p>This is an example of how to solve the <span class="bold_code"><a href="example.html">example problem</a></span> by using a C node. Note that a C node would not typically be used for solving a simple problem like this, a port would suffice.</p>

  <h3><a name="id64088">7.1 
        Erlang Program</a></h3>
    
    <p>From Erlang's point of view, the C node is treated like a normal Erlang node. Therefore, calling the functions <span class="code">foo</span> and <span class="code">bar</span> only involves sending a message to the C node asking for the function to be called, and receiving the result. Sending a message requires a recipient; a process which can be defined using either a pid or a tuple consisting of a registered name and a node name. In this case a tuple is the only alternative as no pid is known.</p>
    <div class="example"><pre>
{RegName, Node} ! Msg</pre></div>
    <p>The node name <span class="code">Node</span> should be the name of the C node. If short node names are used, the plain name of the node will be <span class="code">cN</span> where <span class="code">N</span> is an integer. If long node names are used, there is no such restriction. An example of a C node name using short node names is thus <span class="code">c1@idril</span>, an example using long node names is <span class="code">cnode@idril.ericsson.se</span>.</p>
    <p>The registered name <span class="code">RegName</span> could be any atom. The name can be ignored by the C code, or it could be used for example to distinguish between different types of messages. Below is an example of what the Erlang code could look like when using short node names. 
      </p>
<div class="example"><pre>

-module(complex3).
-export([foo/1, bar/1]).

foo(X) -&gt;
    call_cnode({foo, X}).
bar(Y) -&gt;
    call_cnode({bar, Y}).

call_cnode(Msg) -&gt;
    {any, c1@idril} ! {call, self(), Msg},
    receive
	{cnode, Result} -&gt;
	    Result
    end.
</pre></div>    <p>
      When using long node names the code is slightly different as shown in the following example:
    </p>
<div class="example"><pre>

-module(complex4).
-export([foo/1, bar/1]).

foo(X) -&gt;
    call_cnode({foo, X}).
bar(Y) -&gt;
    call_cnode({bar, Y}).

call_cnode(Msg) -&gt;
    {any, 'cnode@idril.du.uab.ericsson.se'} ! {call, self(), Msg},
    receive
	{cnode, Result} -&gt;
	    Result
    end.
</pre></div>
  

  <h3><a name="id64168">7.2 
        C Program</a></h3>
    

    <h4>Setting Up the Communication</h4>
      
      <p>Before calling any other Erl_Interface function, the memory handling must be initiated.</p>
      <div class="example"><pre>
erl_init(NULL, 0);</pre></div>
      <p>Now the C node can be initiated. If short node names are used, this is done by calling <span class="code">erl_connect_init()</span>.</p>
      <div class="example"><pre>
erl_connect_init(1, "secretcookie", 0);</pre></div>
      <p>The first argument is the integer which is used to construct the node name. In the example the plain node name will be <span class="code">c1</span>.        <br>

        The second argument is a string defining the magic cookie.        <br>

        The third argument is an integer which is used to identify a particular instance of a C node.</p>
      <p>If long node node names are used, initiation is done by calling <span class="code">erl_connect_xinit()</span>.</p>
      <div class="example"><pre>
erl_connect_xinit("idril", "cnode", "cnode@idril.ericsson.se",
                  &amp;addr, "secretcookie", 0);</pre></div>
      <p>The first three arguments are the host name, the plain node name, and the full node name. The fourth argument is a pointer to an <span class="code">in_addr</span> struct with the IP address of the host, and the fifth and sixth arguments are the magic cookie and instance number.</p>
      <p>The C node can act as a server or a client when setting up the communication Erlang-C. If it acts as a client, it connects to an Erlang node by calling <span class="code">erl_connect()</span>, which will return an open file descriptor at success.</p>
      <div class="example"><pre>
fd = erl_connect("e1@idril");</pre></div>
      <p>If the C node acts as a server, it must first create a socket (call <span class="code">bind()</span> and <span class="code">listen()</span>) listening to a certain port number <span class="code">port</span>. It then publishes its name and port number with <span class="code">epmd</span> (the Erlang port mapper daemon, see the man page for <span class="code">epmd</span>).</p>
      <div class="example"><pre>
erl_publish(port);</pre></div>
      <p>Now the C node server can accept connections from Erlang nodes.</p>
      <div class="example"><pre>
fd = erl_accept(listen, &amp;conn);</pre></div>
      <p>The second argument to <span class="code">erl_accept</span> is a struct <span class="code">ErlConnect</span> that will contain useful information when a connection has been established; for example, the name of the Erlang node.</p>
    

    <h4>Sending and Receiving Messages</h4>
      
      <p>The C node can receive a message from Erlang by calling <span class="code">erl_receive msg()</span>. This function reads data from the open file descriptor <span class="code">fd</span> into a buffer and puts the result in an <span class="code">ErlMessage</span> struct <span class="code">emsg</span>. <span class="code">ErlMessage</span> has a field <span class="code">type</span> defining which kind of data was received. In this case the type of interest is <span class="code">ERL_REG_SEND</span> which indicates that Erlang sent a message to a registered process at the C node. The actual message, an <span class="code">ETERM</span>, will be in the <span class="code">msg</span> field.</p>
      <p>It is also necessary to take care of the types <span class="code">ERL_ERROR</span> (an error occurred) and <span class="code">ERL_TICK</span> (alive check from other node, should be ignored). Other possible types indicate process events such as link/unlink and exit.</p>
      <div class="example"><pre>
  while (loop) {

    got = erl_receive_msg(fd, buf, BUFSIZE, &amp;emsg);
    if (got == ERL_TICK) {
      /* ignore */
    } else if (got == ERL_ERROR) {
      loop = 0; /* exit while loop */
    } else {
      if (emsg.type == ERL_REG_SEND) {</pre></div>
      <p>Since the message is an <span class="code">ETERM</span> struct, Erl_Interface functions can be used to manipulate it. In this case, the message will be a 3-tuple (because that was how the Erlang code was written, see above). The second element will be the pid of the caller and the third element will be the tuple <span class="code">{Function,Arg}</span> determining which function to call with which argument. The result of calling the function is made into an <span class="code">ETERM</span> struct as well and sent back to Erlang using <span class="code">erl_send()</span>, which takes the open file descriptor, a pid and a term as arguments.</p>
      <div class="example"><pre>
        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);</pre></div>
      <p>Finally, the memory allocated by the <span class="code">ETERM</span> creating functions (including <span class="code">erl_receive_msg()</span> must be freed.</p>
      <div class="example"><pre>
        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);</pre></div>
      <p>The resulting C programs can be found in looks like the following examples. First a C node server using short node names.</p>
<div class="example"><pre>

/* cnode_s.c */

#include &lt;stdio.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;netinet/in.h&gt;

#include "erl_interface.h"
#include "ei.h"

#define BUFSIZE 1000

int main(int argc, char **argv) {
  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;

  port = atoi(argv[1]);

  erl_init(NULL, 0);

  if (erl_connect_init(1, "secretcookie", 0) == -1)
    erl_err_quit("erl_connect_init");

  /* Make a listen socket */
  if ((listen = my_listen(port)) &lt;= 0)
    erl_err_quit("my_listen");

  if (erl_publish(port) == -1)
    erl_err_quit("erl_publish");

  if ((fd = erl_accept(listen, &amp;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, &amp;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);
      }
    }
  } /* while */
}

  
int my_listen(int port) {
  int listen_fd;
  struct sockaddr_in addr;
  int on = 1;

  if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0)
    return (-1);

  setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &amp;on, sizeof(on));

  memset((void*) &amp;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*) &amp;addr, sizeof(addr)) &lt; 0)
    return (-1);

  listen(listen_fd, 5);
  return listen_fd;
}
</pre></div>      <p>Below follows a C node server using long node names.</p>
<div class="example"><pre>

/* cnode_s2.c */

#include &lt;stdio.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;netinet/in.h&gt;

#include "erl_interface.h"
#include "ei.h"

#define BUFSIZE 1000

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;
  
  port = atoi(argv[1]);

  erl_init(NULL, 0);

  addr.s_addr = inet_addr("134.138.177.89");
  if (erl_connect_xinit("idril", "cnode", "cnode@idril.du.uab.ericsson.se",
			&amp;addr, "secretcookie", 0) == -1)
    erl_err_quit("erl_connect_xinit");

  /* Make a listen socket */
  if ((listen = my_listen(port)) &lt;= 0)
    erl_err_quit("my_listen");

  if (erl_publish(port) == -1)
    erl_err_quit("erl_publish");

  if ((fd = erl_accept(listen, &amp;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, &amp;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)) &lt; 0)
    return (-1);

  setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &amp;on, sizeof(on));

  memset((void*) &amp;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*) &amp;addr, sizeof(addr)) &lt; 0)
    return (-1);

  listen(listen_fd, 5);
  return listen_fd;
}
</pre></div>      <p>And finally we have the code for the C node client.</p>
<div class="example"><pre>

/* cnode_c.c */

#include &lt;stdio.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;netinet/in.h&gt;

#include "erl_interface.h"
#include "ei.h"

#define BUFSIZE 1000

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("e1@idril")) &lt; 0)
    erl_err_quit("erl_connect");
  fprintf(stderr, "Connected to ei@idril\n\r");

  while (loop) {

    got = erl_receive_msg(fd, buf, BUFSIZE, &amp;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);
      }
    }
  }
}
</pre></div>    
  

  <h3><a name="id64499">7.3 
        Running the Example</a></h3>
    
    <p>1. Compile the C code, providing the paths to the Erl_Interface include files and libraries, and to the <span class="code">socket</span> and <span class="code">nsl</span> libraries.</p>
    <p>In R5B and later versions of OTP, the <span class="code">include</span> and <span class="code">lib</span> directories are situated under <span class="code">OTPROOT/lib/erl_interface-VSN</span>, where <span class="code">OTPROOT</span> is the root directory of the OTP installation (<span class="code">/usr/local/otp</span> in the example above) and <span class="code">VSN</span> is the version of the <span class="code">erl_interface</span> application (3.2.1 in the example above).      <br>

      In R4B and earlier versions of OTP, <span class="code">include</span> and <span class="code">lib</span> are situated under <span class="code">OTPROOT/usr</span>.</p>
    <div class="example"><pre>
      
&gt;  <span class="bold_code">gcc -o cserver \\ </span>
<span class="bold_code">-I/usr/local/otp/lib/erl_interface-3.2.1/include \\ </span>
<span class="bold_code">-L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ </span>
<span class="bold_code">complex.c cnode_s.c \\ </span>
<span class="bold_code">-lerl_interface -lei -lsocket -lnsl</span>

unix&gt; <span class="bold_code">gcc -o cserver2 \\ </span>
<span class="bold_code">-I/usr/local/otp/lib/erl_interface-3.2.1/include \\ </span>
<span class="bold_code">-L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ </span>
<span class="bold_code">complex.c cnode_s2.c \\ </span>
<span class="bold_code">-lerl_interface -lei -lsocket -lnsl</span>

unix&gt; <span class="bold_code">gcc -o cclient \\ </span>
<span class="bold_code">-I/usr/local/otp/lib/erl_interface-3.2.1/include \\ </span>
<span class="bold_code">-L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ </span>
<span class="bold_code">complex.c cnode_c.c \\ </span>
<span class="bold_code">-lerl_interface -lei -lsocket -lnsl</span></pre></div>
    <p>2. Compile the Erlang code.</p>
    <div class="example"><pre>
unix&gt; <span class="bold_code">erl -compile complex3 complex4</span></pre></div>
    <p>3. Run the C node server example with short node names.</p>
    <p>Start the C program <span class="code">cserver</span> and Erlang in different windows. <span class="code">cserver</span> takes a port number as argument and must be started before trying to call the Erlang functions. The Erlang node should be given the short name <span class="code">e1</span> and must be set to use the same magic cookie as the C node, <span class="code">secretcookie</span>.</p>
    <div class="example"><pre>
unix&gt; <span class="bold_code">cserver 3456</span>

unix&gt; <span class="bold_code">erl -sname e1 -setcookie secretcookie</span>
Erlang (BEAM) emulator version 4.9.1.2
 
Eshell V4.9.1.2  (abort with ^G)
(e1@idril)1&gt; <span class="bold_code">complex3:foo(3).</span>
4
(e1@idril)2&gt; <span class="bold_code">complex3:bar(5).</span>
10</pre></div>
    <p>4. Run the C node client example. Terminate <span class="code">cserver</span> but not Erlang and start <span class="code">cclient</span>. The Erlang node must be started before the C node client is.</p>
    <div class="example"><pre>
unix&gt; <span class="bold_code">cclient</span>

(e1@idril)3&gt; <span class="bold_code">complex3:foo(3).</span>
4
(e1@idril)4&gt; <span class="bold_code">complex3:bar(5).</span>
10</pre></div>
    <p>5. Run the C node server, long node names, example.</p>
    <div class="example"><pre>
unix&gt; <span class="bold_code">cserver2 3456</span>

unix&gt; <span class="bold_code">erl -name e1 -setcookie secretcookie</span>
Erlang (BEAM) emulator version 4.9.1.2
 
Eshell V4.9.1.2  (abort with ^G)
(e1@idril.du.uab.ericsson.se)1&gt; <span class="bold_code">complex4:foo(3).</span>
4
(e1@idril.du.uab.ericsson.se)2&gt; <span class="bold_code">complex4:bar(5).</span>
10</pre></div>
  
</div>
<div class="footer">
<hr>
<p>Copyright © 2000-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>