Monday, August 22, 2016

Linux IPC, Unix domain socket.

Linux IPC Unix domain of socket is inter process/thread exchanging message as you choose.
I made two examples, one is server socket program, other is client socket program.

unix-dimain-server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

// Make server socket.
//
int makeServer(char* sockName) {

  int                sfd;
  int                ret;
  struct sockaddr_un name;

  // Unlink, last running remove the socket.
  unlink(sockName);

  // Create server socket.
  if((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
    perror("ERROR:Server Socket()");
    return -1;
  }

  // Bind socket
  memset(&name, 0, sizeof(struct sockaddr_un));
  name.sun_family = AF_UNIX;
  strncpy(name.sun_path, sockName, sizeof(name.sun_path) - 1);
  if ((ret = bind(sfd,
                  (const struct sockaddr *)&name,
                  sizeof(struct sockaddr_un) - 1)) < 0) {
    perror("ERROR:Server bind()");
    return -1;
  }

  // Listen, prepair for accept()
  if((ret = listen(sfd, 10)) < 0) {
    perror("ERROR:Server listen()");
    return -1;
  }

  return sfd;
}
// Make data socket for client.
//
int acceptClient(int sfd) {

  int dfd;

  if((dfd = accept(sfd, NULL, NULL)) < 0) {
    perror("ERROR:Server accept()");
    return -1;
  }

  return dfd;
}

// This main()
//
int main(int argc, char** argv) {

  int  sfd, dfd;
  int  ret;
  char buf[256];

  if((sfd = makeServer(argv[1])) < 0) {
    return -1;
  }

  if((dfd = acceptClient(sfd)) < 0) {
    close(sfd);    // Close server socket.
    return -1;
  }

  // Main loop
  while(1) {
    if((ret = read(dfd, buf, sizeof(buf))) < 0) {
      perror("ERROR:Data read()");
      return -1;
    }

    printf("%s", buf);

    if(strncmp(buf, "END", 3) == 0) {
      printf("Received END\n");
      break;
    }

    // Send to client "NeXT".
    if((ret = write(dfd, "NeXT", 4)) < 0) {
      perror("ERROR:Data write()");
      return -1;
    }
  }

  // Send "END" for client.
  write(dfd, "END", 3);

  // Close data socket.
  close(dfd);

  // Close server socket.
  close(sfd);

  return 0;
}


"unix-domain-server" functions.
   1. Create server side accepting socket.
        This program required an argument "socket name".
   2. It wait to connect from client.
   3. Client data receive and server data send to client.
   4. If received data is "END" then send "END" and socket close.

unix-domain-client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define HOST_ADDR "192.168.1.16"
int main(int argc, char** argv) { int dfd; int ret; struct sockaddr_un name; char buf[256]; char rcv[256]; // Create socket if((dfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { perror("ERROR:Client socket()"); return -1; } // Connect server memset(&name, 0, sizeof(struct sockaddr_un)); name.sun_family = AF_UNIX; strncpy(name.sun_path, argv[1], sizeof(name.sun_path) - 1); if((ret = connect(dfd, (const struct sockaddr*)&name, sizeof(struct sockaddr_un) - 1)) < 0) { perror("ERROR:Client connect()"); return -1; } while(1) { // User input to send data. printf("#"); memset(buf, 0, sizeof(buf)); fflush(stdin); fgets(buf, 256, stdin); // Send to server. if((ret = write(dfd, buf, strlen(buf) + 1)) < 0) { perror("ERROR:Client read()"); close(dfd); return -1; } // Reveive data from server. memset(rcv, 0, sizeof(rcv)); if((ret = read(dfd, rcv, sizeof(rcv) - 1)) < 0) { perror("ERROR:Client read()"); close(dfd); return -1; } printf("%s", rcv); if(strncmp(rcv, "END", 3) == 0) { printf("\nReceived END\n"); break; } } // Close data socket. close(dfd); return 0; }


"unix-domain-server" functions.
   1. Create client side socket and connect to server.
        This program required an argument "socket name".
   2. It wait to key input from user.
   3. Inputed data send to server via socket and receive server answer.
   4. If received data is "END" then socket close.

*Server/Client need a argument-1 is socket name.
   Ex. program execution.
      First, server run terminal.
      # touch hogehoge                   --> hogehoge is socket name
      # ./unix-domain-server ./hogeoge

      Then, client run other terminal.
      # ./unix-domain-client ./hogehoge

Good luck and enjoy your programing!


No comments:

Post a Comment