Unix Domain UDP Socket Connection Example

The Unix Domain UDP Socket Connection follows the same method and APIs as the internet (AF_INET) UDP Socket connection

The differences between the AF_INET socket and the Unix Domain Datagram socket are as follows

  • Instead of an IP address – a socket path for the server and the client is required.
  • In an UDP socket – each end (server socket and client socket) connect to separate paths and the server and client use bind API to connect to their respective socket paths.
  • This is different from a stream Unix Domain socket wherein the server and client connect to two ends of the same path and only the server binds to the socket path.
  • The Internet UDP socket is considered unreliable, however, since the UNIX UDP socket is confined to the host system, Unix Domain UDP sockets are reliable
  • The client and server socket paths are chosen as below for the sample programs:

server side socket — /tmp/unix_sock.sock and client side socket — /tmp/unix_client_sock.sock

The code for an UDP UNIX domain socket connection is provided below

Server CodeClient Code

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

struct sockaddr_un *servaddr = NULL, *clientaddr = NULL;
int sock_fd;
char *SOCK_PATH=”/tmp/unix_sock.sock”;

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

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

int main () {
        char buffer[50] = {‘0’};
        char *string = “Hello Client”;
        int length = sizeof(struct sockaddr_un);
        int error;

        signal(SIGINT, interrupt_handler);
        signal(SIGTERM, interrupt_handler);

        /* Part 1 – create the socket */
        if (0 > (sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0))) {
                printf(“unable to create socket\n”);
                exit(0);
        }

        /* Part 2 bind to the socket path */
        remove(SOCK_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;
        snprintf(servaddr->sun_path, (strlen(SOCK_PATH)+1), “%s”, SOCK_PATH);

        if (0 != (bind(sock_fd, (struct sockaddr *)servaddr, sizeof(struct sockaddr_un)))) {
                printf(“bind failed\n”);
                goto end2;
        }

        /* Part 3 – send and receive data to the client */
        clientaddr = (struct sockaddr_un *)malloc(sizeof(struct sockaddr_un));

        if (clientaddr == NULL) {
                printf(“unable to allocate memory\n”);
                goto end2;
        }

        int num_of_bytes;
        while (1) {
                memset(buffer, 0, sizeof(buffer));
                num_of_bytes = recvfrom(sock_fd, buffer, sizeof(buffer), 0, (struct sockaddr *)clientaddr, &length);
                if (num_of_bytes == -1) {
                        printf(“read from client failed\n”);
                        goto end3;
        }
        printf(“%s\n”, buffer);

        memset(buffer, 0, sizeof(buffer));
        snprintf(buffer, (strlen(string)+1), “%s”, string);
        if((sendto(sock_fd, buffer, sizeof(buffer), 0, (struct sockaddr *)clientaddr, length)) != sizeof(buffer)) {
                printf(“errno is %d”, errno);
                printf(“send failed\n”);
                goto end3;
                }
        }

end3:
        free(clientaddr);

end2:
        free(servaddr);
end:
        close(sock_fd);
        return 0;

}

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

struct sockaddr_un *servaddr = NULL, *clientaddr = NULL;
int sockfd;
char *SOCKPATH = “/tmp/unix_client_sock.sock”;
char *SERVERPATH = “/tmp/unix_sock.sock”;

void interrupt_handler (int signal) {
        free(servaddr);
        close(sockfd);
        printf(“connection closed\n”);
}

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

        signal(SIGINT, interrupt_handler);
        signal(SIGTERM, interrupt_handler);

        /* Part 1 – create the socket */
        if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
                printf(“socket creation failed\n”);
                exit(0);
        }

        /*part 2 – fill the client socket details and bind*/
        clientaddr = (struct sockaddr_un *)malloc(sizeof(struct sockaddr_un));
        if (clientaddr == NULL) {
                printf(“unable to allocate memory\n”);
                goto end;
        }
        remove(SOCKPATH);
        clientaddr->sun_family = AF_UNIX;
        snprintf(clientaddr->sun_path, (strlen(SOCKPATH)+1), “%s”, SOCKPATH);

        if( 0 != (bind(sockfd, (struct sockaddr*)clientaddr, sizeof(struct sockaddr_un)))) {
                printf(“Unable to bind at client end\n”);
                goto end;
        }

        /* read and write data */
        servaddr = (struct sockaddr_un *)malloc(sizeof(struct sockaddr_un));
        if (servaddr == NULL) {
                printf(“unable to allocate memory\n”);
                goto end1;
        }

        servaddr->sun_family = AF_UNIX;
        snprintf(servaddr->sun_path, (strlen(SERVERPATH)+1), “%s”, SERVERPATH);

        while (1) {
                memset(buffer, 0, sizeof(buffer));
                snprintf(buffer, (strlen(string)+1), “%s”, string);
                num_of_bytes = sendto(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)servaddr, sizeof(struct sockaddr_un));

                if(num_of_bytes < sizeof(buffer)) {
                        printf(“unable to send data to server\n”);
                        goto end2;
                }

                memset(buffer, 0, sizeof(buffer));
                num_of_bytes = recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL);
                if (num_of_bytes == -1) {
                        printf(“unable to receive data from the server\n”);
                        goto end2;
                }
                printf(“%s\n”, buffer);
        }
end2:
        free(servaddr);
end1:
        free(clientaddr);
end:
        close(sockfd);
        return 0;
}

 

Analyzing the Unix Domain UDP Socket Code

 

Comments

  1. Pingback: Analyzing the Unix Domain Stream Socket Code | Hitch Hiker's Guide to Learning

  2. Pingback: Analyzing the Unix Domain UDP Socket Code | Hitch Hiker's Guide to Learning

  3. Pingback: The Abstract Namespace AF_UNIX Datagram code example | Hitch Hiker's Guide to Learning

Leave a Reply

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