Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make two-directional unix domain sockets with SOCK_DGRAM?

I am trying to write a simple Unix datagram server/client, and am having some problems. What I want is a server that listens on a datagram socket and sends a reply to every message received, to the original sender. I decided to try first using socat to be the "server" and writing the client in C. I am running socat like this:

socat UNIX-DGRAM:/tmp/test.socket,fork EXEC:echo

To the best of my understanding this should listen on /tmp/test.socket and reply to everything that is received with the same string? Then I have a client program that looks like this (error checking removed for clarity):

int s = socket(AF_UNIX, SOCK_DGRAM, 0);
struct sockaddr_un sa;
sa.sun_family = AF_UNIX;
strcpy(sa.sun_path, "/tmp/test.socket");

const char *data = "Testing data";
int err = sendto(s, data, strlen(data), 0, (struct sockaddr *)(&sa), sizeof(struct sockaddr_un));

printf("Sent!\n");

unsigned char *buffer = malloc(BUFFER_LENGTH);
struct sockaddr_storage recv_sa;
int recv_sa_len = 0;
int recv_len = recvfrom(s, buffer, BUFFER_LENGTH, 0, (struct sockaddr *)&recv_sa, &recv_sa_len);

for (int i = 0; i < recv_len; i++) {
    putc(buffer[i], stdout);
}
printf("\n");

It should send the packet (that works), receive a packet, and then print it out, but the program doesn't seem to be capable of receiving the packet. What am I doing wrong here, or do I have a fundamental misunderstanding about Unix sockets? Thanks!

like image 570
fyhuang Avatar asked Sep 06 '11 20:09

fyhuang


People also ask

Are UNIX domain sockets bidirectional?

UNIX domain sockets are a method by which processes on the same host can communicate. Communication is bidirectional with stream sockets and unidirectional with datagram sockets.

Are Linux sockets bidirectional?

A socket in Linux is a bidirectional communication pipe. Unlike standard FIFOs or pipes, work with sockets is done using the sockets interface as opposed to the file interface.

What is the difference between AF_UNIX and Af_inet?

tl,dr: AF_UNIX is for sockets(and they use files) while AF_INET is for binding to ip addresses, and creating communications on its various forms(unicast, multicast, broadcast...).

How do I create a UNIX domain socket in Linux?

To create a UNIX domain socket, use the socket function and specify AF_UNIX as the domain for the socket. The z/TPF system supports a maximum number of 16,383 active UNIX domain sockets at any time. After a UNIX domain socket is created, you must bind the socket to a unique file path by using the bind function.


1 Answers

Take a look at the Michael Kerrisk's AF_UNIX SOCK_DGRAM example of the client/server program (client, server) published in his book The Linux Programming Interface, chapter 57.

like image 54
Igor Avatar answered Nov 01 '22 13:11

Igor