A Socket Server/Client Example – TCP Stream Sockets

TCP is a connection oriented protocol. The socket connection will follow the TCP 3- way handshake to establish the connection. 

In This Article, we take a look at a simple server and client example. The Internet IPv4 domain will be considered for the below example.

The Stream socket will follow the below connection establishment process shown in the diagram. 

FIG Courtesy: The Linux Programming interface, Michael Kerrisk

The client and server program are provided below. We will analyze the code in the next article.

Server CodeClient Code

#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
/* Internet socket structures
* are defined in below header */
#include <netinet/in.h>
/* inet_addr is defined in
* below header */
#include <arpa/inet.h>
#include <signal.h>

/* for Read/write API calls*/
#include <unistd.h>

#define PORT 55000
#define TRUE 1

/* IPv4 socket structures for
* server and client */

struct sockaddr_in *serveraddr = NULL, *clientaddr = NULL;

/* socket file descriptor */
int socket_fd, clientfd;

/* Interrupt_handler – so that CTRL + C can be used to
* exit the program */
void interrupt_handler (int signum) {
        close(socket_fd);
        close(clientfd);

        free(serveraddr);
        free(clientaddr);
        printf(“socket connection closed\n”);
        exit(0);
}

int main () {
         /* length of client structure received on accept */
         int length;
         char buffer[50];
         char *string = “Hello from Server”;

        /* signal handler to exit out of while 1 loop */
        signal (SIGINT, interrupt_handler);
        signal (SIGPIPE, interrupt_handler);

         /* Part 1 – create the socket */

         if((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
                 printf(“unable to create the socket\n”);
                 exit(0);
         }

         /* Part 2 – create the server connection – fill the structure*/
         serveraddr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));

         if (serveraddr == NULL) {
                 printf(“Unable to allocate memory\n”);
                 goto end;
         }

         serveraddr->sin_family = AF_INET;

         /* use loopback address (127.0.0.1)so that
          * the server/client connection
          * can be created on the same machine
          * inet_addr API – Change the IP address from
          * dotted decimal presentation form to an integer form
          * suitable as an internet address */

          serveraddr->sin_addr.s_addr = inet_addr(“127.0.0.1”);
          serveraddr->sin_port = htons(PORT);

          /* Part 3 – bind and start accepting connections */

          if(0 != bind(socket_fd, (struct sockaddr *)serveraddr, sizeof(struct                                                    sockaddr_in))) {
                     printf(“unable to bind to the socket\n”);
                     goto end1;
          }

          /* accept upto 5 pending requests
           * and make the server socket a passive socket
           */ 
          if (listen(socket_fd, 5) == -1) {
                   printf(“Listen Failed\n”);
                  goto end1;
        }

        clientaddr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
        if (clientaddr == NULL) {
                 printf(“unable to allocate memory\n”);
                 goto end1;
        }

       /* accept is a blocking call and the call would stop further invocation of          *  code till a client connection is accepted */
        printf(“waiting for connection\n”);
        clientfd = accept(socket_fd, (struct sockaddr *)clientaddr, &length);

        if (clientfd < 0) {
                 printf(“Unable to connect to Client FD\n”);
                 goto end2;
        }

        /* read and write data from/to client socket */
        while (TRUE) {
               /* Use the client socket FD to read data from the client */
               memset(buffer, 0, sizeof(buffer));
               read(clientfd, buffer, sizeof(buffer));
               printf(“%s\n”, buffer);

              /* write data to the client */
              memset(buffer, 0, sizeof(buffer));
              snprintf(buffer, (strlen(string) + 1), “%s\n”, string);
              write(clientfd, buffer, sizeof(buffer));
        }
end3:
        if (clientfd >= 0)
                 close(clientfd);
end2:
        free(clientaddr);
end1:
        free(serveraddr);
end:
        close(socket_fd);
}

#include <stdio.h>
#include <sys/socket.h>
/* Internet socket structures
* are defined in below header */
#include <netinet/in.h>
/* inet_addr is defined in
* below header */
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

/* For read/write APIs*/
#include <unistd.h>
#define PORT 55000

/* socket file descriptor */
int socket_fd;
/* IPv4 socket structure */
struct sockaddr_in *sockaddrin = NULL;

/* Interrupt_handler so that CTRL +C can be used
* to exit the program */
void interrupt_handler (int signum) {
        close(socket_fd);
        free(sockaddrin);
        printf(“socket connection closed\n”);
        exit(0);
}

int main () {
        char buffer[50] = {0};
        char *string = “Hello from client”;

         /* signal handler to exit out of while 1 loop */
         signal (SIGINT, interrupt_handler);
         signal (SIGPIPE, interrupt_handler);

         /* Part 1 – create a socket */
         /* create the socket FD */
         socket_fd = socket(AF_INET, SOCK_STREAM, 0);

         if (socket_fd < 0) {
                 printf(“The Socket API call failed\n”);
                 exit(0);
         }

          /* Part 2 – allocate server connection details
           * structure for connection */

          /* allocate memory and fill the sockaddr_in structure
           * so that it can be connected to the socket */

          sockaddrin = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
         if (sockaddrin == NULL) {
                  /* unable to allocate memory */
                  goto end;
         }
        sockaddrin->sin_family = AF_INET;
        sockaddrin->sin_port = htons(PORT);

         /* use loopback address (127.0.0.1)so that
          * the server/client connection
          * can be created on the same machine
          * inet_addr API – Change the IP address from
          * dotted decimal presentation form to an integer form
          * suitable as an internet address */
         sockaddrin->sin_addr.s_addr = inet_addr(“127.0.0.1”);

         /* part 3 – connect to the server defined by IP address and port*/
         /* connect to the server */
        if (0 != connect(socket_fd, (struct sockaddr *)sockaddrin,
                (socklen_t)(sizeof(struct sockaddr_in)))) {
                printf(“Unable to connect\n”);
                /* unable to connect to server */
               goto end1;
        }

        /* Part 4 – send/receive data */
        /* read and write data from/to client socket */  
         while (1) {

                 memset(buffer, 0, sizeof(buffer));
                 /* write data to the server */
                 snprintf(buffer, (strlen(string) + 1), “%s\n”, string);
                 write(socket_fd, buffer, sizeof(buffer));

                 memset(buffer, 0, sizeof(buffer));
                 read(socket_fd, buffer, sizeof(buffer));
                 printf(“%s\n”, buffer);
        }
end1:
                free(sockaddrin);
end:
                close(socket_fd);
}

Analysing the Stream socket connection

Comments

  1. Pingback: Basic Socket communication APIs Explained | Hitch Hiker's Guide to Learning

  2. Pingback: Analysing the Stream Socket connection | Hitch Hiker's Guide to Learning

  3. Pingback: IPv6 Socket Code Example | Hitch Hiker's Guide to Learning

Leave a Reply

Your email address will not be published. Required fields are marked *