C Program to Trying out socket communication between processes using the Internet protocol family.

How to write a C Program to Trying out socket communication between processes using the Internet protocol family ?

Solution:

/*
 * Trying out socket communication between processes using the Internet protocol family.
 */

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/times.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>

#define PORT 5558
#define MAXMSG 512

/* makeSocket
 * Creates and names a socket in the Internet
 * name-space. The socket created exists
 * on the machine from which the function is
 * called. Instead of finding and using the
 * machine's Internet address, the function
 * specifies INADDR_ANY as the host address;
 * the system replaces that with the machine's
 * actual address.
 */

 void writeMessage(int fileDescriptor, char *message);
void writeMessage(int fileDescriptor, char *message);

int makeSocket(unsigned short int port) {
      int sock;
      struct sockaddr_in name;

      /* Create a socket. */
      sock = socket(PF_INET, SOCK_STREAM, 0);
      if(sock < 0) {
            perror("Could not create a socket\n");
            exit(EXIT_FAILURE);
      }
      /* Give the socket a name. */
      /* Socket address format set to AF_INET for Internet use. */
      name.sin_family = AF_INET;
      /* Set port number. The function htons converts from host byte order to network byte order.*/
      name.sin_port = htons(port);
      /* Set the Internet address of the host the function is called from. */
      /* The function htonl converts INADDR_ANY from host byte order to network byte order. */
      /* (htonl does the same thing as htons but the former converts a long integer whereas
       * htons converts a short.)
       */
       /*INADDR_ANY = machine's actual address*/
      name.sin_addr.s_addr = htonl(INADDR_ANY);
      /* Assign an address to the socket by calling bind. */
      if(bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) {
            perror("Could not bind a name to the socket\n");
            exit(EXIT_FAILURE);
      }
      return(sock);
}

/* readMessageFromClient
 * Reads and prints data read from the file (socket
 * denoted by the file descriptor 'fileDescriptor'.
 */
int readMessageFromClient(int fileDescriptor) {
      char buffer[MAXMSG];
      int nOfBytes;
      nOfBytes = read(fileDescriptor, buffer, MAXMSG);
      if(nOfBytes < 0) {
            perror("Could not read data from client\n");
            exit(EXIT_FAILURE);
      }
      else
        if(nOfBytes == 0)
              /* End of file */
              return(-1);
        else
        {
              /* Data read */
              printf(">Incoming message: %s\n",  buffer);
              writeMessage(fileDescriptor, "Server: I hear you, dude...\n");
        }

      return(0);
}
void writeMessage(int fileDescriptor, char *message) {
      int nOfBytes;

      nOfBytes = write(fileDescriptor, message, strlen(message) + 1);
      if(nOfBytes < 0) {
            perror("writeMessage - Could not write data\n");
            exit(EXIT_FAILURE);
      }
}

void broadcastMessage(int serverSocket, fd_set *activeFdSet, char *message) {

    for(int i = 0; i < FD_SETSIZE; ++i)
    {
        if(FD_ISSET(i, activeFdSet)) {
            if(i!=serverSocket)
                writeMessage(i, message);
        }
    }
}

int main(int argc, char *argv[]) {
      int sock;
      int clientSocket;
      int i;
      fd_set activeFdSet, readFdSet; /* Used by select */
      struct sockaddr_in clientName;
      socklen_t size;
      char message[128];

      /* Create a socket and set it up to accept connections */
      sock = makeSocket(PORT);
      /* Listen for connection requests from clients */
      if(listen(sock,1) < 0) {
            perror("Could not listen for connections\n");
            exit(EXIT_FAILURE);
      }
      /* Initialize the set of active sockets */
      FD_ZERO(&activeFdSet);
      FD_SET(sock, &activeFdSet);
      printf("\n[waiting for connections...]\n");
      while(1) {
            /* Block until input arrives on one or more active sockets
               FD_SETSIZE is a constant with value = 1024 */
            readFdSet = activeFdSet;
            if(select(FD_SETSIZE, &readFdSet, NULL, NULL, NULL) < 0) {
                  perror("Select failed\n");
                  exit(EXIT_FAILURE);
            }
            /* Service all the sockets with input pending */
            for(i = 0; i < FD_SETSIZE; ++i)
            {
                if(FD_ISSET(i, &readFdSet)) {
                    if(i == sock) {
                          /* Connection request on original socket */
                          size = sizeof(struct sockaddr_in);
                          /* Accept the connection request from a client. */
                          clientSocket = accept(sock, (struct sockaddr *)&clientName, (socklen_t *)&size);
                          if(clientSocket < 0) {
                                perror("Could not accept connection\n");
                                exit(EXIT_FAILURE);
                          }
                          if(strncmp(inet_ntoa(clientName.sin_addr), "127.0.0.1", strlen(inet_ntoa(clientName.sin_addr))+1) == 0)
                          {
                                printf("This is the adress that wont connect\n");
                                writeMessage(clientSocket, "RIP");
                                close(clientSocket);
                                continue;
                          }
                          sprintf(message, "Server: Connect from client %s, port %d\n", inet_ntoa(clientName.sin_addr), ntohs(clientName.sin_port));
                          printf(message);
                          FD_SET(clientSocket, &activeFdSet);
                          broadcastMessage(sock, &activeFdSet, message);
                    }
                    else {
                          /* Data arriving on an already connected socket */
                          if(readMessageFromClient(i) < 0) {
                                close(i);
                                FD_CLR(i, &activeFdSet);
                          }
                    }
                }
            }
      }
}


Learn More :