Friday, 28 August 2020

Shared Libraries with GCC on linux

 

  •  Create an .so file and run that file, link the .so from the same path to the executable.

Program:

Program file 1 Header file  (foo.h):

/* Shared Libraries with GCC on linux
 * Check : http://velrajcoding.blogspot.in
 */
#ifndef foo_h__
#define foo_h__

extern void foo(void);

#endif  // foo_h__

Program file 2 foo.c:
 
/* Shared Libraries with GCC on linux
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>


void foo(void)
{
        printf("Hello, I am a shared library");
}

Program file 3 Main file (main.h):
/* Shared Libraries with GCC on linux
 * Check : http://velrajcoding.blogspot.in
 */
#include <stdio.h>
#include "foo.h"

int main(void)
{
    puts("This is a shared library test...");
    foo();
    return 0;
}

Compile & execute:

Step 1: Compiling with Position Independent Code

[so_crete]$ ls
foo.c foo.h main.c
[so_crete]$
[so_crete]$ gcc -c -Wall -Werror -fpic foo.c
[so_crete]$ ls
foo.c foo.h foo.o main.c
[so_crete]$

Step 2: Creating a shared library from an object file

[so_crete]$ gcc -shared -o libfoo.so foo.o
[so_crete]$ ls
foo.c foo.h foo.o libfoo.so main.c
[so_crete]$

Step 3: Linking with a shared library

[so_crete]$ gcc -Wall -o test main.c -lfoo
/bin/ld: cannot find -lfoo
collect2: error: ld returned 1 exit status
[so_crete]$

Tell GCC where to find the shared library
[so_crete]$ pwd
/users/vkutrala/vel/sample/so_crete
[so_crete]$ gcc -L /users/vkutrala/vel/sample/so_crete -Wall -o test main.c -lfoo
[so_crete]$ ls
foo.c foo.h foo.o libfoo.so main.c test
[so_crete]$

Step 4: Making the library available at runtime

[so_crete]$ ./test
./test: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
[so_crete]$

Using LD_LIBRARY_PATH

[so_crete]$ echo $LD_LIBRARY_PATH

[so_crete]$ LD_LIBRARY_PATH=/users/vkutrala/vel/sample/so_crete:$LD_LIBRARY_PATH
[so_crete]$ ./test
./test: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
[so_crete]$
[so_crete]$
[so_crete]$
What happened? Our directory is in LD_LIBRARY_PATH, but we did not export it. In Linux, if you do not export the changes to an environment variable, they will not be inherited by the child processes
[so_crete]$ export LD_LIBRARY_PATH=/users/vkutrala/vel/sample/so_crete:$LD_LIBRARY_PATH
[so_crete]$ ./test
This is a shared library test...
Hello, I am a shared library
[so_crete]$

Reference:
     https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html

 

Read About Dynamic loading lib(run time load or patch update)

Friday, 31 July 2020

python: how to use pexpect without installing

We can use the pexpect without installing, below is the best way to use:

  1. Downloaded Pexpect 2.4 ( https://pypi.org/project/pexpect/2.4/#files).
    • We tested on python 2.7.10 version, need to check in latest python version, not sure this will work on latest.
    • Also seems not support in latest pexpect version because latest version doesn't have pexpect.py file iteself. so best use pexpect 2.4 version. 
       2. Place pexpect.py next to my script
       3. import pexpect in my script.


It will work.

Monday, 29 July 2019

strtok vs strtok_r - extract tokens from strings

Name

strtok, strtok_r - extract tokens from strings

Synopsis

       #include <string.h>

       char *strtok(char *str, const char *delim);
       char *strtok_r(char *str, const char *delim, char **saveptr);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
       strtok_r(): _POSIX_C_SOURCE
           || /* Glibc versions <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE

Note:

1. Don't use original string pointer because, it will replace the
   delimiters with '\0'.
2. Suppose Original string is constant then crash will be hit.
3. strtok will use the global pointer, so could not use in thread & 
   2 strtok simultaneously.
4. strtok_r is a thread save, because it use the local pointer for
   next iteration.

Description:

  • strtok() and strtok_r() for splitting a string by some delimiter.
  • The strtok() function breaks a string into a sequence of zero or more nonempty tokens.
  • On the first call to strtok(), the string to be parsed should be specified in str.
  • In  each subsequent call that should parse the same string, str must be NULL.
  •  
  • The  delim argument specifies a set of bytes that delimit the tokens in the parsed string.
  • The strtok_r() function is a reentrant  version  strtok().
  • The  saveptr  argument  is a pointer  to  a  char * variable that is used internally by strtok_r() in order to maintain context between successive calls that parse the same string.

 Return:

  • Return a pointer to the next token, or NULL if there are no more tokens.

Program:

/* strtok vs strtok_r by Velraj.K
   Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char *str1, *str2, *token, *subtoken;
    char *saveptr1, *saveptr2;
    char str_second[256] = {'\0'};
   // *str_second = "VelrajKutralam Indian";
    int j;

    if (argc != 4) {
        fprintf(stderr, "Usage: %s  <1st delim="">  <2nd subdelim="">\n",
                argv[0]);
        exit(EXIT_FAILURE);
    }

    /* The original string will be replaced with null in delimiter places */
    strncpy(str_second, argv[1], sizeof(str_second));

    printf("\n\n\t\t Do the token using strtok_r \n");

    /* use strtok_r */
    for (j = 1, str1 = argv[1]; ; j++, str1 = NULL) {
        token = strtok_r(str1, argv[2], &saveptr1);
        if (token == NULL)
            break;
        printf("%d: %s\n", j, token);

        for (str2 = token; ; str2 = NULL) {
            subtoken = strtok_r(str2, argv[3], &saveptr2);
            if (subtoken == NULL)
                break;
            printf(" --> %s\n", subtoken);
        }
    }
   printf("Original value = %s \n", argv[1]);

    printf("\n\n\t\tDo the token using strtok str_second = %s \n", str_second);
    /* Initialize the variable to NULL to start token again with strtok */
    str1 = NULL;
    str2 = NULL;
    token = NULL;
    subtoken = NULL;
    saveptr1 = NULL;
    saveptr2 = NULL;

    /* use strtok */
    for (j = 1, str1 = str_second; ; j++, str1 = NULL) {
        token = strtok(str1, argv[2]);
        if (token == NULL)
            break;
        printf("%d: %s\n", j, token);

       /*
        *  Could not use the 2nd strtok with different delim because it uses the global pointer
        *  to process the next token.
        */
#if 0
        for (str2 = token; ; str2 = NULL) {
            subtoken = strtok(str2, argv[3]);
            if (subtoken == NULL)
                break;
            printf(" --> %s\n", subtoken);
        }
#endif
    }

    exit(EXIT_SUCCESS);
}

 

Output:

:~/velrajk/sample/learn$ ./a.out  velrajkutralamindia l v


                 Do the token using strtok_r
1: ve
 --> e
2: rajkutra
 --> rajkutra
3: amindia
 --> amindia
Original value = ve


                Do the token using strtok str_second = velrajkutralamindia
1: ve
2: rajkutra
3: amindia

Tuesday, 23 July 2019

Dynamic loading lib(run time load or patch update)

dlopen:

void * dlopen(const char *filename, int flag);
Flag:
  RTLD_LAZY --> ``resolve undefined symbols as code from the dynamic library is
                  executed''
  RTLD_NOW  --> ``resolve all undefined symbols before dlopen() returns and 
                  fail if this cannot be done''
                  opening the library take slightly longer (but it speeds up 
                  lookups later);  
  RTLD_GLOBAL --> Optional -> external symbols defined in the library will be made
                  available to subsequently loaded libraries

  • If the libraries depend on each other (e.g., X depends on Y), then you need to load the dependees first (in this example, load Y first, and then X).

Return:

  • ``handle'' that should be considered an opaque value to be used by the other DL library routines.
  • Return NULL On error.

dlerror:

  • which returns a string describing the error from the last call to dlopen(), dlsym(), or dlclose().
  • Return null if there is no error.
  • Call dlerror() first (to clear any error condition that may have existed), then call dlsym() to request a symbol, then call dlerror() again to see if an error occurred.

dlsym:

void * dlsym(void *handle, char *symbol);
      handle -> value returned from dlopen
      symbol -> NIL-terminated string.

Note:

For Run time patch(Dynamic loading the .so file):
   We must close the old handler & re open the library again,if there is
   any change in library. Otherwise changes won't be loaded.
   Hence for Run time patch, we must close & open the library again.

Return:

  • Return a NULL result if the symbol wasn't found.   

dlclose:

  • Closes a DL library.
  •  The dl library maintains link counts for dynamic file handles, so a dynamic library is not actually deallocated until dlclose has been called on it as many times as dlopen has succeeded on it.
  •  It's not a problem for the same program to load the same library multiple times.

Return:

  • Returns 0 on success, and non-zero on error

Program:

Program 1: create shared library:

 

/* Dynamic loading lib(run time load or patch update)
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>

void run_load()
{
    printf("Velraj Run time loading 1st \n");


    return;
}
 

Program 2: Dynamic loader program:

 
/* Dynamic loading lib(run time load or patch update)
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

#define LIB_USR_DEF   "~/velrajk/sample/learn/librunlib.so"

enum {
    DL_LOAD_LIB = 1,
    DL_CALL_FUN,
    DL_EXIT,
};

void hline(char ch)
{
    int i = 0;

    for ( ; i < 80; printf("%c", ch), i++);
    printf("\n");

    return;
}
int main(int argc, char **argv)
{
    void *handle = NULL;
    void (*fun_symbol)();
    char *ret = NULL;
    int  ch = 0;

    while (1) {
        printf("\n\n");
        hline('*');
        printf("Find the DL library options:  \n\t 1. Load the library\n\t 2.Call the function\n\t 3.Exit\n Enter your choice:   ");
        scanf("%d", &ch);

        switch (ch) {
            case DL_LOAD_LIB:
                /*
                 * For Run time path:
                 *       We must close the old handler & re open the library again, if there is any change in library.
                 *       Otherwise changes won't be loaded.
                 *       Hence for Run time patch, we must close & open the library again.
                 */
                if (handle) {
                    dlclose(handle);
                }
                handle = dlopen(LIB_USR_DEF, RTLD_LAZY);
                if (!handle) {
                    fputs (dlerror(), stderr);
                    continue;
                }
                printf("Successfully opened an library \n");
                break;
            case DL_CALL_FUN:
                /* clear error code */
                dlerror();
                fun_symbol = dlsym(handle, "run_load");
                if ((ret = dlerror()) != NULL)  {
                    /* handle error, the symbol wasn't found */
                    printf("dlerror return error msg as:%s \n", ret);
                    continue;
                }

                /* symbol found, calling the symbol */
                (*fun_symbol)();
                break;
            case DL_EXIT:
                exit(1);
                break;
            default:
                printf("Choose the correct choice \n");
                break;
        }
    }

    dlclose(handle);

    return 0;
}
 

Output:

Program 1: Create Library

   :~/velrajk/sample/learn$ gcc -fPIC -shared -o librunlib.so dl_run_lib.c

Program 2: Dynamic loading

   :~/velrajk/sample/learn$ gcc dlopen.c -ldl


:~/velrajk/sample/learn$ ./a.out


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   1
Successfully opened an library


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:



<!-- Here itself changed the library content as 2nd but without dlclose & dlopen, new value won't effect -->

2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   1
Successfully opened an library


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 2nd


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   3

Reference:
    http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html
    https://developer.ibm.com/tutorials/l-dynamic-libraries/
 

Shared library program:   Shared Libraries with GCC on linux


Monday, 22 July 2019

File based Database using Gunzip


  • zlib is a software library used for data compression.
  • The zlib library provides Deflate compression and decompression code for use by zip, gzip, png (which uses the zlib wrapper on deflate data).
  • gzread decompresses as you read it.

Program:

 
/* File based Database using Gunzip
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>
#include <zlib.h>    // For gunzip

enum {
    TAG_VER = 1,
    TAG_DATA,
};

#define FILE_PATH_TMP     "file_gz_db.gz.tmp"
#define FILE_PATH         "file_gz_db.gz"
#define VERSION_1         1
#define STU_ID            100
#define STU_NAME          "Velraj"
#define STU_TOTAL         500

void save_db()
{
    char buf[256] = {0};
    int  len = 0;
    gzFile gz_file = NULL;

    if (!(gz_file = gzopen(FILE_PATH_TMP, "wb"))) {
        printf("Failed gzopen !");
        return;
    }

    len = snprintf(buf, sizeof(buf), "%d\a%d\n", TAG_VER, VERSION_1);
    if (len != gzwrite(gz_file, buf, len)) {
        printf("Failed to writing db header!");
        goto end;
    }

    len = snprintf(buf, sizeof(buf), "%d\a%d\a%s\a%d\n", TAG_DATA,
                   STU_ID, STU_NAME, STU_TOTAL);
    if (len != gzwrite(gz_file, buf, len)) {
        printf("Failed to writing db header!");
        goto end;
    }
    rename(FILE_PATH_TMP, FILE_PATH);

end:
    gzclose(gz_file);
    return;
}

void read_db()
{
    gzFile gz_file = NULL;
    char   buf[256] = {0}, str_tag[16] = {0}, str_stu_id[12] = {0}, str_name[64] = {0}, str_total[12] = {0};
    int    tag = 0, version = 0, ret = 0;

    if (!(gz_file = gzopen(FILE_PATH, "rb"))) {
        printf("gzopen is failed to open the file");
        return;
    }
    if (gzgets(gz_file, buf, sizeof(buf)) == NULL) {
        printf("File is doesn't have any content");
        goto end;
    }

    sscanf(buf, "%d\a%d", &tag, &version);
    if ((tag != TAG_VER) || (version != VERSION_1)) {
        printf("Failed tag or version");
        goto end;
    }

    while (gzgets(gz_file, buf, sizeof(buf))) {
        ret = sscanf(buf, "%d", &tag);
        if (tag != TAG_DATA) {
            continue;
        }

        ret = sscanf(buf, "%*[^\a]\a%[^\a]\a%[^\a]\a%[^\n]", str_stu_id, str_name, str_total);
        if (ret != 3) {
            printf("Failed to read student details ret:%d", ret);
            continue;
        }
        printf("Read the data : ID:%s, Name:%s, Total:%s \n", str_stu_id, str_name, str_total);
    }

end:
    gzclose(gz_file);
    return;
}

int main()
{
    save_db();
    read_db();

    return 0;
}
 

Output:

:~/velrajk/sample$ gcc file_list_of_data.c  -lz
:~/velrajk/sample$ ls -l file_gz_db.gz
ls: cannot access file_gz_db.gz: No such file or directory
:~/velrajk/sample$ ./a.out
Read the data : ID:100, Name:Velraj, Total:500
:~/velrajk/sample$ ls -l file_gz_db.gz
-rw-rw-r-- 1 labuser labuser 41 Jul 22 14:44 file_gz_db.gz
:~/velrajk/sample$ gunzip file_gz_db.gz
:~/velrajk/sample$ cat file_gz_db
11
2100Velraj500
:~/velrajk/sample$





Reference:
https://www.lemoda.net/c/gzfile-read/
https://stackoverflow.com/questions/39233004/zlib-gzopen-returns-a-compressed-file-stream-does-it-decompress-the-file
https://github.com/madler/zlib

Friday, 19 July 2019

Write binary(struct) data to the file using fread, fwrite

NAME

       fread, fwrite - binary stream input/output

SYNOPSIS

#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);


Note:

 3rd Argument is sizeof nmemb:
      nmemb -> number of size to be written into fiile.
              Eg: if 1 then only one node will be written into file.
                  if 2 then two nodes will be written into the file.

DESCRIPTION

  • The function fread() reads nmemb elements of data, each size bytes long, from the stream pointed to by stream, storing them at the location given by ptr.
  • The function fwrite() writes nmemb elements of data, each size bytes long, to the stream pointed to by stream, obtaining them from the location given by ptr.

RETURN VALUE

  • On  success, fread() and fwrite() return the number of items read or written.  This number equals the number of bytes transferred only when size is 1.
  • If an error occurs, or the end of the file is reached, the return value is a short item count (or zero).
  • fread() does not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred.
  • Note: To verify error need to use ferror() API, could not use return value.

Program:

 

/* Write binary(struct) data to the file using fread, fwrite
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>
#include <errno.h>
#include <string.h>

#define FILE_NAME       "binary_fil"
#define FILE_NAME_2     "binary_fil2"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif

typedef struct node {
    int   value1;
    int   value2;
    char  name[64];
} node_t;

void display_node(node_t *node, char *msg)
{
    if (!node || !msg) {
        printf("Node or msg is null \n");
        return;
    }
    printf("Node %s Value 1:%d Value2:%d name:%s \n", msg, node->value1, node->value2, node->name);

    return;
}

int file_write_struct(node_t *node, const char *file, size_t num_node)
{
    FILE        *fp = NULL;

    if (!(fp = fopen(file, "w"))) {
        printf("Error in open an file, error no:%d:<%s> \n", errno, strerror(errno));
        return FALSE;
    }

    /*
     * 3rd Argument is sizeof nmemb:
     *     nmemb -> number of size to be written into fiile.
     *              Eg: if 1 then only one node will be written into file.
     *                  if 2 then two nodes will be written into the file.
     */
    fwrite(node, sizeof(node_t), num_node, fp);
    if (ferror(fp)) {
        printf("Error in write to the file, error no:%d:<%s> \n", errno, strerror(errno));
        return FALSE;
    }
    fclose(fp);

    return TRUE;
}

int file_read_struct(node_t *node)
{
    FILE        *fp = NULL;

    if (!(fp = fopen(FILE_NAME, "r"))) {
        printf("Error in open an file, error no:%d:<%s> \n", errno, strerror(errno));
        return FALSE;
    }

    fread(node, sizeof(node_t), 1, fp);
    if (ferror(fp)) {
        printf("Error in write to the file, error no:%d:<%s> \n", errno, strerror(errno));
        return FALSE;
    }
    fclose(fp);

    return TRUE;
}

int main()
{
    node_t      node[] = { {100, 200, "Velraj Kutralam"},
                           {20, 35, "Kutralam S"} };
    node_t      node_read = {0};

    display_node(node, "before save");
    file_write_struct(node, FILE_NAME, 1);
    file_write_struct(node, FILE_NAME_2, 2);

    file_read_struct(&node_read);
    display_node(node, "after save");

    return 0;
}

 

Output:

:~/velrajk/sample$ ./a.out
Node before save Value 1:100 Value2:200 name:Velraj Kutralam
Node after save Value 1:100 Value2:200 name:Velraj Kutralam
:~/velrajk/sample$ cat binary_fil
d▒Velraj Kutralam:~/velrajk/sample$
:~/velrajk/sample$ cat binary_fil2
d▒Velraj Kutralam#Kutralam S:~/velrajk/sample$


Vim of binary_fil:

d^@^@^@È^@^@^@Velraj Kutralam^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@

Vim of binary_fil2:

^@^@^@È^@^@^@Velraj Kutralam^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^T^@^@^@#^@^@^@Kutralam S^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@


Wednesday, 17 July 2019

Increase socket buffer size using SO_RCVBUF & SO_SNDBUF

SO_RCVBUF

  • The "SO_" prefix is for "socket option"
  • Settings for the per-socket buffers.
  • It is the size of the buffer, the kernel allocates to hold the data arriving into the given socket during the time between it arrives over the network and when it is read by the program that owns this socket.
  • For TCP:
    • If data arrives and you aren't reading it, the buffer will fill up, and the sender will be told to slow down (using TCP window adjustment mechanism).
  • For UDP:
    • once the buffer is full, new packets will just be discarded.

SO_SNDBUF

  • Similary to SO_RCVBUF this is for send buffer.


This is limited at system level by the below file
    # cat /proc/sys/net/core/wmem_max

Note: 

  • In real time, Used TCP local socket for IPC & faced below buffer issue:
  • Process A working on the data & send the value to process B, Process B process this data & response the result back to Process A to update his db.
  • Usually Process A will do only 1 data, at a time, so never faced any issue.
  • Some corner case, process A processing bulk data, and send the data to Process B and not processing the process B response.
  • Hence response from process B is got full & process B start discarding the value due to socket full message.

Solution 1:

  • Increase the socket buffer size using SO_SNDBUF, but could not increase double the system max size "core/wmem_max".
  • Partially issue fixed without increase the system max "core/wmem_max", full complete fix need to increase the system max memory.

Solution 2:

  • Instead of process only bulk data, process A can process 200 bulk data & give few second gap to process the Process B response.
  • And the process the next set of message, batching the bulk data.

Conclusion:

  • Instead of increase the system wide memory, its good to do the batching. Hence batching is selected.

Program:

Makefile:

CC = gcc
SO_FLAGS = -fPIC -shared

exe:libsock.so
        gcc select_stream_cli.c -L . -l sock -o cli -lpthread
        gcc select_stream_ser.c -L . -l sock -o ser

libsock.so:
        $(CC) ../socket_buf_inc.c $(SO_FLAGS) -o ../libsock.so

clean:
        rm libsock.so cli ser


socket_buf_inc.h:

#ifndef __SOCKET_BUF_INC__H__
#define __SOCKET_BUF_INC__H__

void socket_non_blocking(int soc_fd);
void soc_get_so_rcv_buf(int sock_fd, char *msg);
void soc_set_so_rcv_buf(int sock_fd, size_t size);

#endif /* __SOCKET_BUF_INC__H__ */


"../socket_buf_inc.c":


/* Increase socket buffer size using SO_RCVBUF & SO_SNDBUF
 * Check : http://velrajcoding.blogspot.in
 */
#include <stdio .h>
// Below 2 for getsockopt & setsockopt
#include <sys/types.h>
#include <sys/socket.h>

#include <errno.h>  // for errno

#include <unistd.h>  // For fcntl
#include <fcntl.h>   //  For fcntl
#include <string.h>  // For strerror


//#define SO_RCV_BUFFER_SIZE        425984

/******************************************************************************
 * FUNCTION NAME: socket_non_blocking
 *
 * DESCRIPTION  : Set the socket fd as non blocking socket
 *
 * RETURNS      : None
 ******************************************************************************/
void socket_non_blocking(int soc_fd)
{
    int        flags_non_blk = 0;

    if ((flags_non_blk =  fcntl(soc_fd, F_GETFL)) == -1) {
        printf("Failed to get flags, so didn't set the block buffer errno <%d>(%s) \n", errno, strerror(errno));
        return;
    }
    if (fcntl(soc_fd, F_SETFL, (flags_non_blk | O_NONBLOCK)) == -1) {
        printf("Failed to set the block buffer errno <%d>(%s) \n", errno, strerror(errno));
    }
    printf("The socket:%d is set as non-blocking socket \n", soc_fd);

    return;
}


/******************************************************************************
 * FUNCTION NAME: soc_get_so_rcv_buf
 *
 * DESCRIPTION  : Retrieve the socket receive buffer size
 *
 * RETURNS      : None
 ******************************************************************************/
void soc_get_so_rcv_buf(int sock_fd, char *msg)
{
    unsigned int size = 0;
    socklen_t socklen = sizeof(size);

    getsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &size, &socklen);
    printf("Socket receive buffer %s size:%u \n", msg, size);


}

/******************************************************************************
 * FUNCTION NAME: soc_get_so_snd_buf
 *
 * DESCRIPTION  : Retrieve the socket receive buffer size
 *
 * RETURNS      : None
 ******************************************************************************/
void soc_get_so_snd_buf(int sock_fd, char *msg)
{
    unsigned int size = 0;
    socklen_t socklen = sizeof(size);

    getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &size, &socklen);
    printf("Socket send buffer %s size:%u \n", msg, size);

    return;
}


/******************************************************************************
 * FUNCTION NAME: soc_set_so_rcv_buf
 *
 * DESCRIPTION  : Set the socket receive buffer size
 *
 * RETURNS      : None
 ******************************************************************************/
void soc_set_so_rcv_buf(int sock_fd, size_t size)
{
//    unsigned int size = SO_RCV_BUFFER_SIZE;
    socklen_t socklen = sizeof(size);

    soc_get_so_rcv_buf(sock_fd, "Before set the value");
    if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &size, socklen) == -1) {
        printf("Failed to set the socket receive buffer as %zu, errno <%d>(%s)", size, errno, strerror(errno));
    }
    soc_get_so_rcv_buf(sock_fd, "After set the value");

    return;
}

/******************************************************************************
 * FUNCTION NAME: soc_set_so_rcv_buf
 *
 * DESCRIPTION  : Set the socket receive buffer size
 *
 * RETURNS      : None
 ******************************************************************************/
void soc_set_so_snd_buf(int sock_fd, size_t size)
{
    socklen_t socklen = sizeof(size);

    soc_get_so_snd_buf(sock_fd, "Before set the value");
    if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &size, socklen) == -1) {
        printf("Failed to set the socket send buffer as %zu, errno <%d>(%s)", size, errno, strerror(errno));
    }
    soc_get_so_snd_buf(sock_fd, "After set the value");

    return;
}


Server program: select_stream_ser.c

/* Increase socket buffer size using SO_RCVBUF & SO_SNDBUF
 * Check : http://velrajcoding.blogspot.in
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>    // for bool data type
#include <math.h>
#include <signal.h>


#include <sys/ioctl.h>   //* Ioctl & FION
#define ADDRESS         "/home/labuser/highPriority"  /* addr to connect */
#define ADDRESS_LOW     "/home/labuser/lowPriority"  /* addr to connect */

#define FALSE 0
#define TRUE  1
#define SO_RCV_BUFFER_SIZE        425984

struct sock_db;

typedef struct sock_db sock_db_t;

typedef void (*fd_callback_t) (int fd, void *data);

struct sock_db{
    sock_db_t *next;
    int    fd;
    int    sock_domain;
    char   name[128];
    bool   isHighPriority;
    fd_callback_t read_callback;
};

// Globle Declaratoin
int lock = 0;
int gtotal_db = 0;
sock_db_t *top = NULL;
int gDestroyed = 0;

int max(int firstValue, int secondValue)
{
    int result = 0;

    if(firstValue > secondValue)
        result = firstValue;
    else
        result = secondValue;

    return result;
}


int lock_acquire()
{
    lock = 1;
}

int lock_release()
{
    lock = 0;
}

int lock_check_and_wait()
{
    while(lock)
    {
        printf("Vel %s inside lock sleep for 200 milli second  \n", __FUNCTION__);
        usleep(200);
    }
}



void insert_node(sock_db_t *node)
{

    if(!top)
    {
        top = node;
        top->next = NULL;
    }
    else
    {
        node->next = top;
        top = node;
    }
}

sock_db_t *create_entry(char *name, int sock_domain)
{
    sock_db_t *node;

    node = (sock_db_t *)calloc(1, sizeof(sock_db_t));
    if(node == NULL)
    {
        printf("No memory to allocate \n");
        exit(1);
    }

    strcpy(node->name, name);
    node->next = NULL;
    node->sock_domain = sock_domain;

    lock_check_and_wait();
    lock_acquire();

    insert_node(node);

    gtotal_db++;
    lock_release();

    return node;
}

int ipc_init_unix(char *path, fd_callback_t callback)
{
    int flags = 1; /*to set to non-blocking*/
    int len;
    struct sockaddr_un saun, clun;
    sock_db_t *sock_entry = NULL;



    sock_entry = create_entry("db_un", AF_UNIX);

    /*
     * get a socket to work with.  this socket will
     * be in the unix domain, and will be a
     * stream socket.
     */

    sock_entry->fd = socket(AF_UNIX, SOCK_STREAM, 0);

    if ((sock_entry->fd) < 0) {
        perror("server: socket");
        exit(1);
    }

   /*Set it to non-blocking fd*/
    ioctl(sock_entry->fd, FIONBIO, &flags);

    saun.sun_family = AF_UNIX;
    strcpy(saun.sun_path, path);

    unlink(path);
    len = sizeof(saun.sun_family) + strlen(saun.sun_path);

    if(!strcmp(path, ADDRESS))
        sock_entry->isHighPriority = 1;
    else
        sock_entry->isHighPriority = 0;

    if (bind(sock_entry->fd, (struct sockaddr *) &saun, len) < 0) {
        perror("server: bind");
        exit(1);
    }

    soc_get_so_rcv_buf(sock_entry->fd, "Socket");
    if (listen(sock_entry->fd, 4) < 0)
    {
        return -1;
    }
    sock_entry->read_callback = callback;

    return sock_entry->fd;
}

sock_db_t *find_entry(int fd)
{
    sock_db_t *sock_entry = top;

    while(sock_entry)
    {
        if(sock_entry->fd == fd)
            return sock_entry;
        sock_entry = sock_entry->next;
    }

    return NULL;

}


int  destroy(int des_fd)
{
    sock_db_t *temp = top, *prev = NULL;

    lock_check_and_wait();
    lock_acquire();

    prev = temp;
//    printf("Vel %s %p %p %p \n", __FUNCTION__, top, temp, prev);
    while(temp)
    {
        if(temp->fd == des_fd)
        {
            if(temp == top)
            {
                top = top->next;
                free(temp);
            }
            else
            {
                prev->next = temp->next;
                free(temp);
            }
            gDestroyed = 1;

            gtotal_db--;
            goto end;
        }
        prev = temp;
        temp = temp->next;
    }

end:
    lock_release();

}
void client_recv(int cli_fd, void *data)
{
    char str[128] = {0};

    sock_db_t *sock_entry = NULL;
    int nbyteRec = 0;

    sock_entry = find_entry(cli_fd);

    if(!sock_entry)
    {
        printf("Error Count not find the fd = %d \n",cli_fd);
        return;
    }

    printf("Sleep for 4 second before process the msg \n");
    sleep(4);

    memset(str, 0, sizeof(str));
    nbyteRec = read(cli_fd, str, sizeof(str));
    str[nbyteRec] = '\0';

    *(int*)data = nbyteRec;

    if(nbyteRec)
        printf("Msg Received:: Fd = %d Name= %s, Msg= %s ", cli_fd, sock_entry->name, str);
    else if(nbyteRec ==0)
    {
        printf("Vel %s Received byte is 0. Destory the Fd = %d \n", __FUNCTION__, cli_fd);
        destroy(cli_fd);
    }
    else
        perror("Read failure ");

    fflush(stdout);
}

void client_accept(int listen_fd, void *data)
{
     sock_db_t *server, *cli;
     struct sockaddr_un client_addr;
     int addrlen = 0, flags = 1, fd = 0;

     server = find_entry(listen_fd);

     addrlen = sizeof(client_addr);
     fd = accept(listen_fd, (struct sockaddr *)&client_addr, &addrlen);
     if(fd < 0)
         return;

     cli = create_entry("db", server->sock_domain);

     cli->isHighPriority = server->isHighPriority;
     cli->fd = fd;

     /*
      * Since the send is got failed, so needed to increase only the buffer in sender side,
      * Don't need to increase in receiver side. Hence commented below line
      */
     //soc_set_so_rcv_buf(cli->fd, SO_RCV_BUFFER_SIZE);

    /*Set it to non-blocking fd*/
     ioctl(cli->fd, FIONBIO, &flags);


     *(int *) data = cli->fd;
     printf("Vel %s Find new clinet = %d \n", __FUNCTION__, cli->fd);
     cli->read_callback = client_recv;
}

char gFdList[256] = {0};
int fdset_prepare(fd_set *read_fd_set)
{
     int maxfd = -1, nOfClient = 0;
     sock_db_t *sock_entry = top;
     char temp[16];

     FD_ZERO(read_fd_set);

     memset(gFdList, 0, sizeof(gFdList));

     while(sock_entry)
     {
         if(sock_entry->read_callback)
         {
             FD_SET(sock_entry->fd, read_fd_set);
             maxfd = max(sock_entry->fd, maxfd);
             sprintf(temp,"%d, ",sock_entry->fd);
             strcat(gFdList, temp);
         }
         sock_entry = sock_entry->next;
         nOfClient++;
     }

     return maxfd;
}
//#define DEBUG

int fdset_process(fd_set *read_fd_set, int *nready)
{
    sock_db_t *db_high = top, *db_low = top;
    int countHigh = 0, countLow = 0;
    int high_read_cout = 0, low_read_count = 0;
    int recv_count = 0, count_not_high = 0, count_not_low = 0;

    bool isFlagHighEndDB = FALSE, isFlagLowEndDB = FALSE;

    high_read_cout = 6;
    low_read_count = 3;

        //countHigh = 1;
        //countLow = 1;
    while((db_high || db_low)&& ((isFlagHighEndDB == FALSE) || (isFlagLowEndDB == FALSE)))
    {

#ifdef DEBUG
        printf("Vel %s inside while  \n", __FUNCTION__);
#endif
        while(countHigh < high_read_cout && db_high)
        {
//    printf("Vel %s inside while  fd= %d Lw fd = %d is-Hi = %d  \n", __FUNCTION__, db_high->fd,db_low->fd, (int) FD_ISSET(db_high->fd, read_fd_set));
            if(FD_ISSET(db_high->fd, read_fd_set) && db_high->read_callback && db_high->isHighPriority)
            {
                db_high->read_callback(db_high->fd, &recv_count);

                if(gDestroyed == 1)
                {
                    printf("Stop processing the Client Since the Database is modified \n");
                    return 0;
                }

                if(recv_count <=0)
                {
                    int temp = db_high->fd;
                    FD_CLR(temp, read_fd_set);
                }

                (*nready)--;
                /* Here using 2 loop for single database. So if there is any change in database(EG: Client disconnect the link)
                   then 2nd loop will be affected. Used gDestoryed to stop looping.
                   Need to check this condition in our  if we use the 2 while loop. */

                countHigh++;
            }
            else
                count_not_high++;
                                         

            db_high = db_high->next;
            if(db_high == NULL)
            {
//                printf("Vel %s Start again High priority from Top gtotal_db = %d countNot = %d \n", __FUNCTION__, gtotal_db, count_not_high);
                if(count_not_high != gtotal_db)
                    db_high = top;
                count_not_high = 0;
                isFlagHighEndDB = TRUE;
            }

        }

//#ifdef DEBUG
#if 0
        printf("Vel %s inside while after high prir= %d  H= %p L= %p\n", __FUNCTION__, countHigh, db_high, db_low);
#endif
        while(countLow < low_read_count && db_low)
        {
//    printf("Vel %s  LFd= %d   is -low= %d \n", __FUNCTION__, db_low->fd, (int) FD_ISSET(db_low->fd, read_fd_set));
            if(FD_ISSET(db_low->fd, read_fd_set) && db_low->read_callback && (db_low->isHighPriority == 0))
            {
                db_low->read_callback(db_low->fd, &recv_count);
                if(gDestroyed == 1)
                {
                    printf("Stop processing the Client Since the Database is modified \n");
                    return 0;
                }

                if(recv_count <=0)
                {
                    int temp = db_low->fd;
                    FD_CLR(temp, read_fd_set);
                }

                (*nready)--;
                countLow++;
            }
            else
               count_not_low++;

            db_low = db_low->next;
//            printf("Vel %s Start again low priority from Top gtotal = %d countlow = %d \n", __FUNCTION__, gtotal_db, count_not_low);
            if(db_low == NULL)
            {
                if(count_not_low != gtotal_db)
                    db_low= top;
                count_not_low = 0;
                isFlagLowEndDB = TRUE;
            }
        }
    }

//    printf("Vel %s End *** \n", __FUNCTION__);

}

int ipc_handle_input(unsigned int wait_sec, unsigned int wait_usec)
{
    struct timeval timeout;
    int max_fd = 0, nready = 0;
    fd_set rd_fds;

    timeout.tv_sec = wait_sec;
    timeout.tv_usec = wait_usec;


    max_fd = fdset_prepare(&rd_fds);

    nready = select(max_fd+1, &rd_fds, NULL, NULL, &timeout);
    if (nready < 0)
    {
        printf("Vel Error in reading Select \n");
        return 2;
    }
    else if (nready == 0)
    {
         printf("Timed out !! Available Client FD list = %s \r\n", gFdList);
         timeout.tv_sec = 300;
         timeout.tv_usec = 0;
    }
    else
    {
//        printf("Vel %s process \n", __FUNCTION__);
        fdset_process(&rd_fds, &nready);
    }

    return 0;
}

main()
{
    int sock= 0, sockHigh= 0;

    sock = ipc_init_unix(ADDRESS_LOW, client_accept);
    sockHigh = ipc_init_unix(ADDRESS, client_accept);


    while(1)
    {
        gDestroyed = 0;
        ipc_handle_input(300,0);
    }

   /*
     * We can simply use close() to terminate the
     * connection, since we're done with both sides.
     */
    close(sock);
    close(sockHigh);

    exit(0);
}



Client program: select_stream_cli.c

/* Increase socket buffer size using SO_RCVBUF & SO_SNDBUF
 * Check : http://velrajcoding.blogspot.in
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h> // for pthread
#include <sys/ioctl.h>
#include <signal.h>
#include <errno.h>

#define NSTRS         3           /* no. of strings  */
#define ADDRESS       "/home/labuser/highPriority"  /* addr to connect */
#define ADDRESS_LOW   "/home/labuser/lowPriority"  /* addr to connect */
#define SO_SND_BUFFER_SIZE        425984

int connectToIPCconnection(char *path)
{
    int s;
    struct sockaddr_un sockaddun = {0};

    /*
     * Get a socket to work with.  This socket will
     * be in the UNIX domain, and will be a
     * stream socket.
     */
    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        perror("client: socket");
        exit(1);
    }

    /*
     * Create the address we will be connecting to.
     */
    sockaddun.sun_family = AF_UNIX;
    strcpy(sockaddun.sun_path, path);

    if(connect(s, (struct sockaddr *)&sockaddun, sizeof(struct sockaddr_un)) < 0)
    {
        printf("Vel Error connectiong \n");
    }


//    soc_set_so_snd_buf(s, SO_SND_BUFFER_SIZE);
    return s;
}
struct sockidstruct
{
    int sockId;
    char  name[128];
};

void *thread_send_high_message(void *sockDetails)
{
    int i, iSendBytes = 0;
    struct sockidstruct *saunDet = NULL;
    char str[128];

    saunDet = sockDetails;

    /* Send high priority message to server */
    for (i = 0; i < 800; i++)
    {
      //  if(i == 40)
        //    usleep(1);
        memset(str, 0, sizeof(str));
        snprintf(str, sizeof(str), "HIGH priority Msg from client = \"%s\" Number of message = %d \n", saunDet->name, i+1);
        iSendBytes = sendto(saunDet->sockId, str, sizeof(str) /* strlen(str)*/, 0 /*MSG_DONTWAIT */,NULL, 0);

        if(iSendBytes > 0)
        {
            printf("Send High Msg byte = %d Msg count = %d \n", iSendBytes, i+1);
        } else {
            printf("Error in sending errno %d:%s\n", errno, strerror(errno));
        }

    }
    return NULL;
}

void *thread_send_low_message(void *sockDetails)
{
    int i, iSendBytes = 0;
    struct sockidstruct *saunDet = NULL;
    char str[128];

    saunDet = sockDetails;

    /* Send Low priority message to server */
    for (i = 0; i < 40; i++)
    {
///        if(i == 20)
   //         usleep(1);
        memset(str, 0, sizeof(str));
        snprintf(str, sizeof(str), "LOW priority Msg from client = \"%s\" Number of message = %d \n", saunDet->name, i+1);
        iSendBytes = sendto(saunDet->sockId, str, sizeof(str) /*strlen(str)*/, 0 /*MSG_DONTWAIT */, NULL, 0);
        if(iSendBytes > 0 )
            printf("Send Low Msg Byte = %d msg count = %d \n", iSendBytes, i+1);
    }

    return NULL;
}

int main(int argc , char **argv)
{
    char c;
    int i, sockHigh, sockLow;
    pthread_t thread_id_high, thread_id_low;
    struct sockidstruct saunIdDet, saunIdDetLow;
    /*
     * Flags:
     *     1 -> For non blocking
     *     0 -> For blocking
     */

    int flags = 1, HighLowOrBoth = 0;


//    printf("vel argc = %d 1= %s 2 = %s  \n", argc, argv[0], argv[1]);
    if(argc >1 )
    {
        strcpy(saunIdDet.name, argv[1]);
        strcpy(saunIdDetLow.name, argv[1]);

        if(argc >2)
        {
            HighLowOrBoth = atoi(argv[2]);
        }
    }

    sockHigh = connectToIPCconnection(ADDRESS);
    sockLow = connectToIPCconnection(ADDRESS_LOW);

        /*Set it to non-blocking fd*/
     ioctl(sockLow, FIONBIO, &flags);
     ioctl(sockHigh, FIONBIO, &flags);

  //  socket_non_blocking(sockHigh);
  //  socket_non_blocking(sockLow);

    saunIdDet.sockId = sockHigh;
    saunIdDetLow.sockId = sockLow;

    //sleep(1);
    if(HighLowOrBoth == 0)
    {
        pthread_create(&thread_id_low, NULL, &thread_send_low_message, &saunIdDetLow);
        pthread_create(&thread_id_high, NULL, &thread_send_high_message, &saunIdDet);
        printf("Vel High & LOW both Message will be send... \n");
    }
    else if(HighLowOrBoth == 1)
    {
        pthread_create(&thread_id_high, NULL, &thread_send_high_message, &saunIdDet);
        printf("Vel Only High Message will be send");

    }
    else
    {
        pthread_create(&thread_id_low, NULL, &thread_send_low_message, &saunIdDetLow);
        printf("Vel Only Low Message will be send");
    }

    pthread_join(thread_id_high, NULL);
//    pthread_join(thread_id_low, NULL);
//    sleep(20);

    /*
     * We can simply use close() to terminate the
     * connection, since we're done with both sides.
     */
    close(sockHigh);
    close(sockLow);

    exit(0);
}



Output:


Without Increase the buffer:


Server:

 set_soc_buffer/tcp$ ./ser
Socket receive buffer Socket size:212992
Socket receive buffer Socket size:212992
Vel client_accept Find new clinet = 5
Vel client_accept Find new clinet = 6
Sleep for 4 second before process the msg
Msg Received:: Fd = 6 Name= db, Msg= LOW priority Msg from client = "" Number of message = 1
 Sleep for 4 second before process the msg

^C

Client:


set_soc_buffer/tcp$ ./cli
Vel High & LOW both Message will be send...
Send Low Msg Byte = 128 msg count = 1
Send Low Msg Byte = 128 msg count = 2
Send Low Msg Byte = 128 msg count = 3
Send Low Msg Byte = 128 msg count = 4
Send Low Msg Byte = 128 msg count = 5
Send Low Msg Byte = 128 msg count = 6
Send Low Msg Byte = 128 msg count = 7
Send Low Msg Byte = 128 msg count = 8
Send Low Msg Byte = 128 msg count = 9
Send Low Msg Byte = 128 msg count = 10
Send Low Msg Byte = 128 msg count = 11
Send Low Msg Byte = 128 msg count = 12
Send Low Msg Byte = 128 msg count = 13
Send Low Msg Byte = 128 msg count = 14
Send Low Msg Byte = 128 msg count = 15
Send Low Msg Byte = 128 msg count = 16
Send High Msg byte = 128 Msg count = 1
Send Low Msg Byte = 128 msg count = 17
Send Low Msg Byte = 128 msg count = 18
Send Low Msg Byte = 128 msg count = 19
Send Low Msg Byte = 128 msg count = 20
Send Low Msg Byte = 128 msg count = 21
Send Low Msg Byte = 128 msg count = 22
Send Low Msg Byte = 128 msg count = 23
Send Low Msg Byte = 128 msg count = 24
Send Low Msg Byte = 128 msg count = 25
Send Low Msg Byte = 128 msg count = 26
Send Low Msg Byte = 128 msg count = 27
Send Low Msg Byte = 128 msg count = 28
Send Low Msg Byte = 128 msg count = 29
Send Low Msg Byte = 128 msg count = 30
Send Low Msg Byte = 128 msg count = 31

.
.
.
-----Same mesage just icnremnet upto 276 ----
Send High Msg byte = 128 Msg count = 277
Send High Msg byte = 128 Msg count = 278
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable


Increment the send buffer alone and check:



Server Output:

 set_soc_buffer/tcp$ ./ser
Socket receive buffer Socket size:212992
Socket receive buffer Socket size:212992
Socket receive buffer Before set the value size:212992
Socket receive buffer After set the value size:425984
Vel client_accept Find new clinet = 5
Socket receive buffer Before set the value size:212992
Socket receive buffer After set the value size:425984
Vel client_accept Find new clinet = 6
Sleep for 4 second before process the msg
Msg Received:: Fd = 6 Name= db, Msg= LOW priority Msg from client = "" Number of message = 1
 Sleep for 4 second before process the msg
Msg Received:: Fd = 6 Name= db, Msg= LOW priority Msg from client = "" Number of message = 2
 Sleep for 4 second before process the msg
Msg Received:: Fd = 6 Name= db, Msg= LOW priority Msg from client = "" Number of message = 3
 Sleep for 4 second before process the msg
Msg Received:: Fd = 5 Name= db, Msg= HIGH priority Msg from client = "" Number of message = 1
 Sleep for 4 second before process the msg
Msg Received:: Fd = 5 Name= db, Msg= HIGH priority Msg from client = "" Number of message = 2
 Sleep for 4 second before process the msg
Msg Received:: Fd = 5 Name= db, Msg= HIGH priority Msg from client = "" Number of message = 3
 Sleep for 4 second before process the msg
Msg Received:: Fd = 5 Name= db, Msg= HIGH priority Msg from client = "" Number of message = 4
 Sleep for 4 second before process the msg
Msg Received:: Fd = 5 Name= db, Msg= HIGH priority Msg from client = "" Number of message = 5
 Sleep for 4 second before process the msg
Msg Received:: Fd = 5 Name= db, Msg= HIGH priority Msg from client = "" Number of message = 6
 Sleep for 4 second before process the msg
Msg Received:: Fd = 6 Name= db, Msg= LOW priority Msg from client = ""


Client Output:

set_soc_buffer/tcp$ ./cli
Socket send buffer Before set the value size:212992
Socket send buffer After set the value size:425984
Socket send buffer Before set the value size:212992
Socket send buffer After set the value size:425984
Vel High & LOW both Message will be send...
Send Low Msg Byte = 128 msg count = 1
Send Low Msg Byte = 128 msg count = 2
Send Low Msg Byte = 128 msg count = 3
Send Low Msg Byte = 128 msg count = 4
Send Low Msg Byte = 128 msg count = 5
Send Low Msg Byte = 128 msg count = 6
Send Low Msg Byte = 128 msg count = 7
Send Low Msg Byte = 128 msg count = 8
Send Low Msg Byte = 128 msg count = 9
Send Low Msg Byte = 128 msg count = 10
Send Low Msg Byte = 128 msg count = 11
.
.
.
-----Same mesage just icnremnet upto 551 ---- Send High Msg byte = 128 Msg count = 552
Send High Msg byte = 128 Msg count = 553
Send High Msg byte = 128 Msg count = 554
Send High Msg byte = 128 Msg count = 555
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sending errno 11:Resource temporarily unavailable
Error in sendin

 
Reference:
    https://stackoverflow.com/questions/4257410/what-are-so-sndbuf-and-so-recvbuf