The APIs and the steps in establishing data transfer are Similar to a AF_UNIX Datagram socket connection. For the interested reader, the AF_UNIX datagram socket details can be read at the below link locations.
AF_UNIX Datagram code analysis
The difference being that the path for the client and the server are of abstract origin rather than the linux file-system. The code example for the server and the client are provided below
#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=”#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 */
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);
servaddr->sun_path[0] = ‘\0’;
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;
}
/* read and write data */
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 = “#unix_client_sock.sock”;
char *SERVERPATH = “#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;
}
clientaddr->sun_family = AF_UNIX;
snprintf(clientaddr->sun_path, (strlen(SOCKPATH)+1), “%s”, SOCKPATH);
clientaddr->sun_path[0] = ‘\0’;
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);
servaddr->sun_path[0] = ‘\0’;
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 AF_UNIX Abstract Namespace Datagram socket Code example
Pingback: Analyzing the Abstract Namespace stream socket code | Hitch Hiker's Guide to Learning
Pingback: Analyzing the AF_UNIX Abstract Namespace Datagram socket code example | Hitch Hiker's Guide to Learning