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
#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
Pingback: Analyzing the Unix Domain Stream Socket Code | Hitch Hiker's Guide to Learning
Pingback: Analyzing the Unix Domain UDP Socket Code | Hitch Hiker's Guide to Learning
Pingback: The Abstract Namespace AF_UNIX Datagram code example | Hitch Hiker's Guide to Learning