Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Communicating between NodeJS and C using node-ipc and unix sockets

I want to communicate between NodeJS and a C program using node-ipc, over a Unix socket, which according to that homepage is the fastest option. (They will be on the same machine). That package claims it could communicate with a C program. (I had to sanity check).

The problem is the examples don't give example C code, and I have next to no idea how I'd get them to talk.

Can anyone point me to an example of C code to match those client/server examples? For example, how would I adapt this tutorial on working with unix pipes in C (Assuming I'm not completely off track?! Maybe it's "domain sockets" that I want instead?) None of this is making any sense to me, I'm missing something crucial.

like image 278
CL22 Avatar asked Oct 03 '16 23:10

CL22


People also ask

What is ipc NodeJS?

'node-ipc' is a Node. js module for local and remote Inter Process Communication with full support for Linux, Mac and Windows. It also supports all forms of socket communication from low level unix and windows sockets to UDP and secure TLS and TCP sockets.

What protocol does Nodejs use?

Node.js has a built-in module called HTTP, which allows Node.js to transfer data over the Hyper Text Transfer Protocol (HTTP).

Who made node ipc?

0 and 10.1. 2) are now tracked under CVE-2022-23812. Brandon Nozaki Miller, aka RIAEvangelist, is the node-ipc creator and seems to have designed these two versions as a peaceful protest act, as they primarily put a “message of peace” (hence the heart emoji) to every Russia or Belarus based developer who installs them.


2 Answers

I got it to work in the end with the code below. You can have it for free!

server.c

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>

char *socket_path = "/tmp/icp-test";

int main(int argc, char *argv[]) {
  struct sockaddr_un addr;
  char buf[100];
  int fd,cl,rc;

  if (argc > 1) socket_path=argv[1];

  if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    perror("socket error");
    exit(-1);
  }

  memset(&addr, 0, sizeof(addr));
  addr.sun_family = AF_UNIX;
  if (*socket_path == '\0') {
    *addr.sun_path = '\0';
    strncpy(addr.sun_path+1, socket_path+1, sizeof(addr.sun_path)-2);
  } else {
    strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
    unlink(socket_path);
  }

  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
    perror("bind error");
    exit(-1);
  }

  if (listen(fd, 5) == -1) {
    perror("listen error");
    exit(-1);
  }

  while (1) {
    if ( (cl = accept(fd, NULL, NULL)) == -1) {
      perror("accept error");
      continue;
    }

    while ( (rc=read(cl,buf,sizeof(buf))) > 0) {
      printf("read %u bytes: %.*s\n", rc, rc, buf);
    }
    if (rc == -1) {
      perror("read");
      exit(-1);
    }
    else if (rc == 0) {
      printf("EOF\n");
      close(cl);
    }
  }
  return 0;
}

client.js:

 var ipc=require('node-ipc');

var socketId = 'icp-test';
ipc.config.id   = 'hello';
ipc.config.socketRoot = '/tmp/';
ipc.config.appspace = '';

ipc.config.retry= 1500;
ipc.connectTo(
  socketId,
  function(){
    ipc.of[socketId].on(
      'connect',
      function(){
        console.log("Connected!!");
        ipc.log('## connected to world ##'.rainbow, ipc.config.delay);
        ipc.of[socketId].emit(
          'message',  //any event or message type your server listens for
          'hello'
        )
      }
    );
    ipc.of[socketId].on(
      'disconnect',
      function(){
        console.log("Disconnected!!");
        ipc.log('disconnected from world'.notice);
      }
    );
    ipc.of[socketId].on(
      'message',  //any event or message type your server listens for
      function(data){
        console.log("Got a message!!");
        ipc.log('got a message from world : '.debug, data);
      }
    );
  }
);

On a side note, I've realised that if you just want to do communicate between NodeJS via unix sockets with C, NodeJS actually comes with a module that does that already. Which as it turns out, is what node-ipc uses under the hood. So it might be easier just to use NodeJS's net package instead. This previous question points out how to do IPC in NodeJS. Just combine that with the above C code.

like image 99
CL22 Avatar answered Oct 05 '22 23:10

CL22


I think that you should be looking for C unix domain sockets, not pipes. Pipes are different. Look for some C code examples on Google with unix domain sockets, try a few out, get that working, then go back to the node-ipc stuff.

I took the node-ipc and node.js tags off because Node isn't relevant if you are trying to figure out the C side first.

like image 34
Jason Livesay Avatar answered Oct 05 '22 22:10

Jason Livesay