8

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.

5
  • Are you trying to communicate the programs in both directions? Is this a commercial project? Would you pay for help? Commented Oct 3, 2016 at 23:42
  • Yes, both directions. Paying for help isn't really an option, I just need a nudge in the right direction. I was going to use ZeroMQ but it seems like total overkill Commented Oct 4, 2016 at 0:02
  • 1
    If it's on a POSIX system, it's a very simple task in fact. Sadly, I can't help you for free, or answering here since I consider that you need more than simple help. Unix Domain Sockets is the way to go, and I am sure if you google it right you will find plenty of examples with c code included. And it's a very simple thing in fact, just like a regular socket but with a different address and type. Commented Oct 4, 2016 at 0:06
  • C has no significant here. You just need a language that can make system calls. If you're speaking over the network, it really doesn't matter what language you use. Commented Oct 4, 2016 at 1:12
  • I would like to request more information about this, are you able/willing to share your project so I can learn more? Commented Jun 6, 2019 at 22:22

2 Answers 2

18

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.

Sign up to request clarification or add additional context in comments.

3 Comments

#include <string.h> to squelch some warnings
@Jodes - this is really helpful! How did you achieve the two way communication? How do you pass data from the c server to the client? Also, my goal is to use express on the client so that it will receive requests and at some point to pass some work to the c server. Do you have any idea if the requests will be namespaced or do I need threads?
@Jodes I have asked a question to clarify passing data in the reverse direction: stackoverflow.com/questions/52755754/…
4

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.