Trying to make a server on a unix-datagram socket.

#include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #include <stdio.h> #define SERVSOCKNAME "/dev/shm/mysocket" int main(int argc, char **argv) { int len; unsigned char buf[20]; int unsockfd= socket(AF_UNIX, SOCK_DGRAM, 0); if(unsockfd<0) { perror("Create socket"); return 1; } { struct { sa_family_t sun_family; char sun_path[sizeof SERVSOCKNAME]; /* pathname */ } addr= {AF_UNIX, SERVSOCKNAME}; unlink(SERVSOCKNAME); if(bind(unsockfd, (const struct sockaddr *)&addr, sizeof addr)) { perror("Bind socket"); return 1; } } struct sockaddr src_addr[2]; socklen_t addrlen= sizeof src_addr; len=recvfrom(unsockfd, buf, sizeof buf, 0, src_addr, &addrlen); if(len<0) { perror("recvfrom socket"); return 1; } fprintf(stderr, "%d %d '%.*s'\n", sizeof src_addr, addrlen, len, buf); len= sendto(unsockfd, "Respose", 8, 0, src_addr, addrlen); if(len<0) { perror("sendto socket"); return 1; } fprintf(stderr, "sent %d\n",len); } 

And the client to him:

 #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #include <stdio.h> #define SERVSOCKNAME "/dev/shm/mysocket" int main(int argc, char **argv) { int len; unsigned char buf[20]; int unsockfd= socket(AF_UNIX, SOCK_DGRAM, 0); if(unsockfd<0) { perror("Create socket"); return 1; } struct { sa_family_t sun_family; char sun_path[sizeof SERVSOCKNAME]; /* pathname */ } srv_addr= {AF_UNIX, SERVSOCKNAME}; len= sendto(unsockfd, "Request", 8, 0, (const struct sockaddr *)&srv_addr, sizeof srv_addr); if(len<0) { perror("sendto socket"); return 1; } fprintf(stderr, "sent %d\n",len); len=read(unsockfd, buf, sizeof buf); if(len<0) { perror("read socket"); return 1; } fprintf(stderr, "%d '%.*s'\n", len, len, buf); } 

After a client request, the server generates an error:

 32 0 'Request' sendto socket: Transport endpoint is not connected 

This is understandable, since the length of the address is zero, it is not clear where to send the answer. The question is how to organize the reception and transmission?

Similar question on the English version

    1 answer 1

    The problem is solved by client binding . To receive packets (not a stream), the client must also have an address. Binding of a unix-socket in linux is possible either with a namespace in the file system or using abstract addresses. The latter is done automatically if you specify an address length equal to sizeof(sa_family_t) , and a unique address is allocated that is 6 bytes long (not counting sun_family ), the first of which is zero, and the socket file is not created:

     #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #include <stdio.h> #define SERVSOCKNAME "/dev/shm/mysocket" int main(int argc, char **argv) { int len; unsigned char buf[20]; int unsockfd= socket(AF_UNIX, SOCK_DGRAM, 0); if(unsockfd<0) { perror("Create socket"); return 1; } struct { sa_family_t sun_family; char sun_path[sizeof SERVSOCKNAME]; /* pathname */ } srv_addr= {AF_UNIX, SERVSOCKNAME}; if(bind(unsockfd, (const struct sockaddr *)&srv_addr, sizeof(sa_family_t))) { perror("Bind socket"); return 1; } len= sendto(unsockfd, "Request", 8, 0, (const struct sockaddr *)&srv_addr, sizeof srv_addr); if(len<0) { perror("sendto socket"); return 1; } fprintf(stderr, "sent %d\n",len); len=read(unsockfd, buf, sizeof buf); if(len<0) { perror("read socket"); return 1; } fprintf(stderr, "%d '%.*s'\n", len, len, buf); }