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

22
October 11, 2018, at 6:30 PM

This question follows on from the following:

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

In regards to the accepted solution (https://stackoverflow.com/a/39848936/1834057), I was wondering if someone might be able to clarify exactly how to send data from C to Node.js. The solution demonstrates sending data from Node.js to C, but not in reverse. I have an application that requires two-way communications, so the missing component is critical for me.

My understanding of unix sockets that one of either write, send or sendmsg should be able to do the job, however, I am not having any luck. If this understanding is incorrect, please advise.

In order to get a trivial example running, lets say when a message is read in the C code, lets send back a message and try to trigger the ipc.of[socketId].on('message',...) event on the node server.

Which means I am trying to turn this:

while ( (rc=read(cl,buf,sizeof(buf))) > 0) {
      printf("read %u bytes: %.*s\n", rc, rc, buf);
}

Into this:

while ( (rc=read(cl,buf,sizeof(buf)) ) > 0) {
  printf("read %u bytes: %.*s\n", rc, rc, buf);
  //Respond to the node server
  int n;
  char * msg = "{\"type\":\"message\",\"data\":\"hello response\"}\t";
  if((n = write(fd,msg,sizeof(msg))) < 0){
      printf("send failed\n");
  }else{
      printf("sent %d bytes\n", n);
  }
}

This would mean that the complete server.c code now becomes:

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <string.h> //Missing from original server.c
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);
      //Respond to the node server
      int n;
      char * msg = "{\"type\":\"message\",\"data\":\"hello response\"}\t";
      if((n = write(fd,msg,sizeof(msg))) < 0){
          printf("send failed\n");
      }else{
          printf("sent %d bytes\n", n);
      }
    }
    if (rc == -1) {
      perror("read");
      exit(-1);
    }
    else if (rc == 0) {
      printf("EOF\n");
      close(cl);
    }
  }
  return 0;
}

Now unfortunately, the write message for me returns code -1, and is not received by the node.js server.

The client.js code remains unchanged, and is as provided in the original question.

Can someone please clarify what I am doing wrong?

READ ALSO
How to decode eval(&#39;eval(function

How to decode eval('eval(function

I'm learning js, I've search this question, but i can't find any solution for decode eval('eval(function

28
close tab window browser after change page

close tab window browser after change page

I want to use a button in a desktop app that will close the current browser tabthe script works fine if I have opened that page for the first time, but isn't working I use it in a second page

11
Laravel Unit test login of inactive user

Laravel Unit test login of inactive user

I would like to test the case when a user is marked as inactive in db, here is the method in LoginController

10
can not login when i add login with mobile functionality php

can not login when i add login with mobile functionality php

i have a login form in which user can login through mobile number or email or username now when i login through mobile number it works fine but when i login through username or email it says invalid how to make it works and when i remove the query for mobile...

43