`
kylewu
  • 浏览: 4755 次
  • 性别: Icon_minigender_1
  • 来自: 天津
最近访客 更多访客>>
社区版块
存档分类
最新评论

Erlang CNode 代码

阅读更多
好久没写了,一直忙着看文档,今天写个简单的吧

现在所作的项目是建立Erlang的MSC,并与C的OpenBSC连接
由于是C 和 Erlang的连系,所以需要用到C Node
下面的代码是简单的C Node,如果加上OpenBSC,就可以实现ping pong消息的传递

代码很简单,连ip port以及erlang node的名字都是写死了,大伙凑合看吧

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h> 
#include <netinet/in.h>
#include "erl_interface.h"
#include "ei.h"

#include <openbsc/ipaccess.h>

#define BUFSIZE 1000


static const u_int8_t pong[]  = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_PONG };
static const u_int8_t ping[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_PING };

int new_socket;

int prepare_socket(){
    int socket_desc;
    struct sockaddr_in address;

    int bufsize=1024;
    char *buffer=malloc(bufsize);
    int addrlen;

    socket_desc=socket(AF_INET,SOCK_STREAM,0);
    if (socket_desc==-1)
    perror("Create socket");

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(5000);

    bind(socket_desc,(struct sockaddr *)&address,sizeof(address));
    listen(socket_desc,3);

    addrlen = sizeof(struct sockaddr_in);
    new_socket = accept(socket_desc, (struct sockaddr *)&address, &addrlen);
    if (new_socket<0)
    printf("Accept connection");

    printf("recv_from_bsc\n");
    recv(new_socket,buffer,bufsize,0);
    free( buffer );
    return new_socket;
}

int send_ping(){
    int bufsize = 1024;
    char *buff = malloc(bufsize);
    int new_socket;
    new_socket = prepare_socket();
    send( new_socket, pong, sizeof( pong ), 0);
    send( new_socket, ping, sizeof( ping ), 0);
    recv( new_socket, buff, sizeof( buff ), 0);
    //close(new_socket);
    return 0;
}

int send_pong(){
    int new_socket;
    prepare_socket();
    send(new_socket, pong, sizeof( pong ), 0);
    close(new_socket);
    return 0;
}

int main(int argc, char **argv) {
  struct in_addr addr;                     /* 32-bit IP number of host */
  char* ip;
  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;

  fprintf(stderr, "cn ip_address port\n");

  ip = "127.0.0.1";
  port = 5555;
  /*ip = argv[1];*/
  /*port = atoi(argv[2]);*/
  /*printf("ip %s, port %d\n", ip, port);*/

  /*if(argc != 3) return 1;*/

  erl_init(NULL, 0);

  addr.s_addr = inet_addr(ip);

  if (erl_connect_xinit("wenbin-desktop", "cnode", "cnode@wenbin-desktop.xxxxxxx",
            &addr, "wenbin", 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) {
        // get msg
    fromp = erl_element(2, emsg.msg);
    tuplep = erl_element(3, emsg.msg);

        // get elements in the tuple
    fnp = erl_element(1, tuplep);
    //argp = erl_element(2, tuplep);

    if (strncmp(ERL_ATOM_PTR(fnp), "ping", 4) == 0) {
      res = send_ping();
    } else if (strncmp(ERL_ATOM_PTR(fnp), "pong", 4) == 0) {
      res = send_pong();
    } else if (strncmp(ERL_ATOM_PTR(fnp), "stop", 4) == 0) {
      break;
    }

    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);
      }
    }
    printf("Done, waiting for another one.\n");
  }
  printf("Finish.\n");
}
  
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;
}


-module(test_node_ping).

-export([ping/0, pong/0, stop/0]).

stop() ->
    call_cnode( { stop } ).
ping() ->
    call_cnode( { ping } ).

pong() ->
    call_cnode( { pong } ).

call_cnode(Msg) ->
    {any, 'cnode@wenbin-desktop.xxxxxx'} ! {call, self(), Msg},
    if Msg == { stop } ->
        ok;
    true ->
        receive
        {cnode, Result} ->
            Result
        end
    end.
0
0
分享到:
评论

相关推荐

    Erlang_CNode用户指

    7. **案例研究和示例代码**:提供实际的应用场景和代码示例,帮助用户更好地理解和应用CNode技术。 **更多erlang资料下载.txt** 这个文件名可能指向一个包含额外Erlang学习资源的列表,如其他教程、文档、开源项目...

    Erlang_CNode用户指南

    CNode是Erlang VM(BEAM)与C代码之间的桥梁,它允许开发者在C语言中实现Erlang过程。CNode允许Erlang和C之间进行通信,包括消息传递、调用Erlang函数、接收Erlang数据类型等。这为需要高性能计算或利用现有C库的...

    远古封神+英雄远征的ERLANG游戏服务器代码

    《远古封神》与《英雄远征》是两款受欢迎的网络游戏,它们的后端服务器采用了ERLANG这一编程语言来构建。ERLANG是一种为并发、分布式和容错系统设计的函数式编程语言,因其在实时系统和大规模并发处理中的优秀性能而...

    erlang-cnode-example

    - 调试CNode代码可能需要结合Erlang的`dbg`模块或第三方工具,如GDB,以便跟踪C和Erlang的执行流程。 6. **编译和加载CNode模块** - 编译CNode模块时,需要链接`-lerl_interface`和`-lei`库。 - 加载CNode模块到...

    erlang代码热替换与应用部署

    本文将深入探讨Erlang中的代码热替换(Code Replacement)技术及其在应用部署中的重要性。 代码热替换是Erlang的一大特色,它允许在不中断运行服务的情况下更新和替换正在运行的代码。这一特性使得Elang系统可以在...

    KMP(Erlang)代码实现

    由于部分内容中存在OCR扫描错误,但整体上代码逻辑清晰,我们能够理解其算法实现的要点,以及如何利用Erlang的特性来编写高效的字符串匹配算法。这种语言的函数式编程风格使得代码具有很好的可读性和易理解性。在...

    rabbitmq + erlang +代码 一整套完整全部有

    rabbitmq + erlang +代码 一整套完整全部有

    [Erlang程序设计]源代码

    **Erlang程序设计源代码详解** Erlang是一种面向并发、函数式编程语言,尤其在分布式系统和高可用性领域表现出色。本资源包含了《Erlang程序设计》一书的所有实例代码,旨在帮助读者深入理解Erlang语言的核心特性和...

    erlang并发编程实战源代码

    erlang并发编程实战源代码erlang并发编程实战源代码

    Erlang程序设计].源代码

    这些源代码可能是书中实例的实现,或者是针对Erlang编程技巧和概念的示例。通过阅读和分析这些源代码,你可以深入理解Erlang的关键特性: 1. 函数式编程:Erlang是一种纯函数式语言,这意味着函数没有副作用,相同...

    改进erlang版的protobuf代码

    标题中的“改进erlang版的protobuf代码”指的是在Erlang编程语言中对Protocol Buffers(protobuf)进行了优化和改进的代码实现。Protocol Buffers是一种数据序列化协议,由Google开发,它允许开发者定义数据结构,...

    erlang源码包

    例如,`tar -zxvf otp_src_R16B02.tar.gz`将解压出源代码目录。 3. **编译源码**:进入解压后的源码目录,执行配置脚本`./configure`来检测系统环境并准备编译。接着,使用`make`命令进行编译,这将生成Erlang的可...

    二郎助手erlang开发工具、erlang编辑器

    二郎助手的核心特性在于其全面的Erlang支持,包括语法高亮、代码自动完成、错误检查和调试功能。作为一个基于VS2005开发的项目,它继承了Visual Studio家族的强大编辑器功能,并且针对Erlang语言进行了优化。这意味...

    Erlang程序设计及源代码打包

    5. **热代码替换**:Erlang允许在运行时更新代码,无需停止服务,这对于维护和升级系统非常有利。 **随书源代码分析** `jaerlang-code.zip`文件包含了书中示例代码,这些代码可以帮助读者更好地理解书中的概念。...

    Erlang应用部署与热代码替换--理解2

    本篇将深入探讨Erlang应用的部署与热代码替换。 一、Erlang应用部署 在Erlang环境中,应用通常被打包成一个`.app`文件,包含应用元数据,以及一个或多个beam文件(编译后的Erlang代码)。部署Erlang应用的步骤如下...

    erlang写的一个特别的web服务器

    emongrel2的源代码仓库(如GitHub)可能包含详细的README文件和示例,帮助开发者理解和使用这个服务器。 总的来说,emongrel2是Erlang对Mongrel2的实现,它结合了Erlang的并发优势和Mongrel2的设计理念,旨在构建一...

    Erlang程序设计第2版附书代码

    在深入理解Erlang程序设计第2版的附书代码之前,我们先来了解一下Erlang的基本概念和特性。 1. **并发与并行**:Erlang的并发模型基于轻量级进程(Lightweight Processes, LWP),这些进程具有独立的执行路径,可以...

    Erlang程序设计,包含完整目录和全套源码

    5. **模块和函数**:Erlang的模块化设计有助于组织代码,函数是代码的基本执行单元。 6. **错误处理和监控**:Erlang提供了丰富的错误处理机制,如异常处理和过程监视,以及一套完整的监督和恢复机制。 7. **...

    麻将带鬼牌的胡牌提示的完整逻辑,erlang语言代码实现

    erlang语言实现麻将带鬼牌的胡牌提示的完整代码, 三鬼100毫秒以内,四鬼200毫秒 完整逻辑,可自行翻译为任意开发语言

    erlang25.0 windows版本

    作为“源码软件”,Erlang 25.0同样提供了源代码,开发者可以深入研究其内部工作原理,进行定制化开发,或者为Erlang社区贡献代码。对于开发者而言,理解Erlang的源码可以帮助他们更好地利用这个平台,实现更高效、...

Global site tag (gtag.js) - Google Analytics