I am trying to use AF_UNIX sockets under Mac Os X, and I have made a structure that contains some information:
typedef struct
{
int socket;
int conn;
struct sockaddr addr;
}socket_info;
And I use these functions:
socket_info* server_init(void)
{
socket_info* result=(socket_info*)malloc(sizeof(socket_info));
socklen_t length=sizeof(struct sockaddr);
bzero(&(result->addr),sizeof(struct sockaddr));
result->socket=socket(AF_UNIX,SOCK_STREAM,0);
(result->addr).sa_family=AF_UNIX;
(result->addr).sa_len=sizeof(struct sockaddr);
strcpy((result->addr).sa_data,"./mysock");
bind(result->socket,&(result->addr),length);
listen(result->socket,MAX);
result->conn=accept(result->socket,&(result->addr),&length);
return result;
}
socket_info* client_init(socket_info* info)
{
socket_info* result=(socket_info*)malloc(sizeof(socket_info));
result->socket=socket(AF_UNIX,SOCK_STREAM,0);
while( connect(result->socket,&(info->addr),sizeof(struct sockaddr))==-1)
{
if(errno==ENOENT)
{
sleep(1);
}
else
{
fprintf(stderr,"Error: %d",errno);
free(result);
result=NULL;
}
}
return result;
}
And I use them in main:
int main(int argc, char** argv)
{
socket_info *server_info, *client_info;
pid_t pid;
int fd[2];
pipe(fd);
pid=fork();
if(pid==0)
{
char buffer[100];
read(fd[0], server_info, sizeof(struct sockaddr));
client_info=client_init(server_info);
read(client_info->socket,buffer,100);
printf("Messaggio ricevuto: %s",buffer);
}
else
{
const char* msg="ciao";
server_info=server_init();
write(fd[1],server_info,sizeof(struct sockaddr));
write(server_info->socket,msg,sizeof(msg));
}
close(fd[0]);
close(fd[1]);
return 0;
}
But the client fails to connect: instead it prints the message: “Error: 61”.
What could be the reason?
You have two main issues:
You have a classic race condition. If the client tries to connect before the server sets up to listen, the client will get an error.
Your server doesn’t check for any errors, so it could be failing and you wouldn’t know it.
In either case, you’ll get exactly the error you are getting (connection refused).
My money is on the first problem. If you flip the client and server so the child is the server, it will likely go from “happening not to work” to “happening to work”. Most operating systems let the child run first because that saves a ton of memory and eliminates huge numbers of page faults in the typical case where the child just calls
exec.