Abstract Namespace AF_UNIX stream socket code example

To get a basic understanding of an abstract Namespace socket connection, refer the article provided here. To create a socket connection path which does not have an entry in the filesystem, the below method is used

const char *path= “#unix_socket.sock”;

The ‘#‘ in the above name will be replaced with ‘\0‘ (Null byte) when it needs to bind to a path. This is in contrast to the path that was created in the basic AF_UNIX connection as shown below.

const char *path= “/tmp/unix_socket.sock”;

When a “\0” is used in the path, the operating system understands the path to be an abstract path and creates a path accordingly. Let us look at an abstract namespace socket code and analyze the code for the same.

Server CodeClient code

#include <stdio.h>
#include <stdlib.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>

const char *path= “#unix_socket.sock”;

struct sockaddr_un *servaddr = NULL, *cliaddr = NULL;
int sockserver, sockclient;

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

int main () {

        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 */
        sockserver = socket(AF_UNIX, SOCK_STREAM, 0);
        if (sockserver < 0) {
                printf(“creating server socket failed\n”);
                exit(0);
        }
        /* Part 2 – fill the structure and bind to the socket path
        */

        servaddr = (struct sockaddr_un *)malloc(sizeof(struct sockaddr_un));
        if (servaddr == NULL) {
                printf(“unable to allocate memory\n”);
                goto end;
        }
        servaddr->sun_family = AF_UNIX;

        if ((strlen(path)) > sizeof(servaddr->sun_path)) {
                printf(“Path is too long\n”);
                goto end;
        }
        snprintf(servaddr->sun_path, (strlen(path)+1), “%s”, path);
        servaddr->sun_path[0] = ‘\0’;

        if (0 != (bind(sockserver,(struct sockaddr *)servaddr, sizeof(struct sockaddr_un)))) {
                printf(“Unable to bind to the socket path\n”);
                goto end1;
        }

        /* Part 3 – make the server socket a passive socket and accept connections
         * from client stations */

        if(-1 == listen(sockserver, 1)) {
                printf(“Listen Failed\n”);
                return -1;
        }
        cliaddr = (struct sockaddr_un *)malloc(sizeof(struct sockaddr_un));
        if (cliaddr == NULL) {
                printf(“Unable to allocate memory\n”);
                goto end2;
        }
        printf(“waiting for connection\n”);
        sockclient = accept(sockserver, (struct sockaddr *)cliaddr, &length);

        if (sockclient < 0) {
                printf(“unable to accept client connection\n”);
                goto end2;
        }

        /* read and write data from/to socket */
        while (1) {
                memset(buffer, 0, sizeof(buffer));
                read(sockclient, buffer, sizeof(buffer));
                printf(“%s\n”, buffer);

                memset(buffer, 0, sizeof(buffer));
                snprintf(buffer, (strlen(string)+1), “%s”, string);
                write(sockclient, buffer, sizeof(buffer));
        }

end3:
        if(sockclient >= 0)
                close(sockclient);
end2:
        free(cliaddr);
end1:
        free(servaddr);
end:
        close(sockserver);
        return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>

const char *path= “#unix_socket.sock”;

struct sockaddr_un *servaddr = NULL;
int sockserver;

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

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

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

        /* Part 1 – create the socket */
        sockserver = socket(AF_UNIX, SOCK_STREAM, 0);
        if (sockserver < 0) {
                printf(“creating client socket failed\n”);
                exit(0);
        }
        /* Part 2 – fill the structure and bind to the socket path */
        servaddr = (struct sockaddr_un *)malloc(sizeof(struct sockaddr_un));
        servaddr->sun_family = AF_UNIX;

        if ((strlen(path)) > sizeof(servaddr->sun_path)) {
                printf(“Path is too long\n”);
                goto end1;
        }
        snprintf(servaddr->sun_path, (strlen(path)+1), “%s”, path);
        servaddr->sun_path[0] = ‘\0’;

        if (0 != (connect(sockserver, (struct sockaddr *)servaddr, sizeof(struct sockaddr_un)))) {
                printf(“unable to connect to the server\n”);
                goto end1;
        }

        /* read and write data from/to socket */
        while (1) {
                memset(buffer, 0, sizeof(buffer));
                snprintf(buffer, (strlen(string)+1), “%s”, string);
                write(sockserver, buffer, sizeof(buffer));

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

        return 0;
}

Analyzing the Abstract Namespace stream socket code

Comments

  1. Pingback: Abstract Namespace Socket Connections | Hitch Hiker's Guide to Learning

  2. Pingback: Anayzing the Abstract Namespace stream socket code | Hitch Hiker's Guide to Learning

Leave a Reply

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