The key of making sockets in abstract namespace work is providing the proper length to 'bind' and 'connect' commands. To avoid setting '\0' at the end of the address in sockaddr_un it should be copied with strncpy or alike.
It is already explained in Pawel's answer so I'm just going to give an example.
Server:
int main(int argc, char** argv)
{
//to remove warning for unused variables.
int dummy = argc;
dummy = (int)argv;
int fdServer = 0;
int fdClient = 0;
int iErr = 0;
int n = 0;
socklen_t addr_len = 0;
char buff[1024];
char resp[1024];
const char* const pcSocketName = "/tmp/test";
struct sockaddr_un serv_addr;
//set the structure with 'x' instead of 0 so that we're able
//to see the full socket name by 'cat /proc/net/unix'
//you may try playing with addr_len and see the actual name
//reported in /proc/net/unix
memset(&serv_addr, 'x', sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
serv_addr.sun_path[0] = '\0';
//sizeof(pcSocketName) returns the size of 'char*' this is why I use strlen
strncpy(serv_addr.sun_path+1, pcSocketName, strlen(pcSocketName));
fdServer = socket(PF_UNIX, SOCK_STREAM, 0);
if(-1 == fdServer) {
printf("socket() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
}
iErr = bind(fdServer, (struct sockaddr*)&serv_addr, offsetof(struct sockaddr_un, sun_path) + 1/*\0*/ + strlen(pcSocketName));
if(0 != iErr) {
printf("bind() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
}
iErr = listen(fdServer, 1);
if(0 != iErr) {
printf("listen() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
}
addr_len = sizeof(pcSocketName);
while(1) {
fdClient = accept(fdServer, (struct sockaddr*) &serv_addr, &addr_len);
if(0 >= fdClient) {
printf("accept() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
}
memset(resp, 0, sizeof(resp));
memset(buff, 0, sizeof(buff));
n = recv(fdClient, buff, sizeof(buff), 0);
if(0 > n) {
printf("recv() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
}
printf("[client]: %s\n", buff);
sprintf(resp, "echo >> %s", buff);
n = send(fdClient, resp, sizeof(resp), 0);
if(0 > n) {
printf("send() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
}
printf("[server]: %s\n", resp);
}
close(fdServer);
return(0);
}
Client:
int main(int argc, char** argv) {
//to remove warning for unused variables.
int dummy = argc;
dummy = (int)argv;
int fdClient = 0;
struct sockaddr_un serv_addr;
int iErr = 0;
const char* const pcSocketName = "/tmp/test";
char buff[1024];
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
serv_addr.sun_path[0] = '\0';
strncpy(serv_addr.sun_path+1, pcSocketName, strlen(pcSocketName));
fdClient = socket(PF_UNIX, SOCK_STREAM, 0);
if(-1 == fdClient) {
printf("socket() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
}
iErr = connect(fdClient, (struct sockaddr*) &serv_addr, offsetof(struct sockaddr_un, sun_path) + 1/*\0*/ + strlen(pcSocketName));
if(0 != iErr) {
printf("connect() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
}
memset(buff, 0, sizeof(buff));
sprintf(buff, "Hello from client!");
printf("[client]: %s\n", buff);
iErr = send(fdClient, buff, sizeof(buff), 0);
if(0 > iErr){
printf("write() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
}
iErr = recv(fdClient, buff, sizeof(buff), 0);
if(0 > iErr){
printf("read() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
}
printf("[server]: %s\n", buff);
return(0);
}