Wednesday, August 24, 2016

Linux IPC, Inet domain socket.

Linux IPC Internet domain of socket can communicate inter process/thread exchanging message on individually CPU(PC).
I made two examples, one is server socket program, other is client socket program on network.

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

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// Make server socket.
//
int makeServer(int portNo) {

  int                sfd;
  int                ret;
  struct sockaddr_in serv;

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

  // Bind socket
  memset(&serv, 0, sizeof(struct sockaddr_in));
  serv.sin_family = AF_INET;
  serv.sin_addr.s_addr = htonl(INADDR_ANY);
  serv.sin_port = htons(portNo);
  if ((ret = bind(sfd,
                  (const struct sockaddr *)&serv,
                  sizeof(struct sockaddr_in))) < 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  portNo;
  int  ret;
  char buf[256];

  // Check running argument.
  if(argc < 2) {
    printf("inet-domain-server port-No.\n");
    return -1;
  }
  portNo = atoi(argv[1]);

  if((sfd = makeServer(portNo)) < 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.
It needs one arguments, port-number.
   1. Create server side accepting socket.
   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.

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

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define HOST_ADDR "192.168.1.16"

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

  int                dfd;
  int                portNo;
  int                ret;
  struct sockaddr_in serv;
  struct hostent*    servAddr;
  char               buf[256];
  char               rcv[256];

  // Check running argument.
  if(argc < 3) {
    printf("inet-domain-client server-address port-No.\n");
    return -1;
  }
  portNo = atoi(argv[2]);

  // Create socket
  if((dfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    perror("ERROR:Client socket()");
    return -1;
  }

  // Connect server
  memset(&serv, 0, sizeof(struct sockaddr_in));
  serv.sin_family = AF_INET;
  serv.sin_port = htons(portNo);
  if((servAddr = gethostbyname(argv[1])) == NULL) {
    perror("ERROR:Client gethostbyname()");
    return -1;
  }
  bcopy((char*)servAddr->h_addr,
        (char*)&serv.sin_addr.s_addr,
        servAddr->h_length);

  if((ret = connect(dfd,
                    (const struct sockaddr*)&serv,
                    sizeof(struct sockaddr))) < 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.
It needs two arguments, Server-Address(or name) and port-number.
   1. Create client side socket and connect to server.
        This program require tow argument for creation a socket, server-address and port-number.
   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.

Ex. program execution.
      First, server run a terminal.
      # ./inet-domain-server 9999       ---> "9999" is example.

      Then, client run other terminal.
      # ./inet-domain-client 192.168.1.10 9999
               ---> "192.168.1.10" is example server address.
               ---> "9999" is same server made socket port number.

Good luck and enjoy your programing!


No comments:

Post a Comment