Reputation: 25
In implementing a UNIX domain socket the connection is always refused:
if ((my_sock=socket(AF_LOCAL,SOCK_STREAM,0))<0){
syslog(LOG_USER|LOG_ERR,"Could not create tsdmd socket!!");
printf("Couldn't create socket \n");
exit(-1);
}
printf("Socket created \n");
/* Name the socket */
memset(&s_addr, 0,sizeof(struct sockaddr_un));
s_addr.sun_family = AF_LOCAL;
strncpy(s_addr.sun_path,"/tmp/dsock",strlen("/tmp/dsock")+1);
s_addr_size=(offsetof(struct sockaddr_un, sun_path)
+strlen(s_addr.sun_path)+1);
unlink("/tmp/dsock");
if(bind(my_sock,(struct sockaddr *)&s_addr, s_addr_size)<0)
{ printf("BIND ERROR \n");
close(my_sock);
exit(1);
}
printf("Bind successful to the socket !! \n");
if(listen(my_sock,16)==-1)
{ perror("Listen error !! \n");
exit(-1);
}
printf("Listening to socket \n");
if(connect(my_sock,(struct sockaddr *) &s_addr,s_addr_size)==-1)
{
syslog(LOG_USER|LOG_ERR,"Could not connect, will try later");
perror("connect()");
printf("Couldn't connect to socket... will try later \n");
close(my_sock);
my_sock=-1;
}
else
{
FD_SET(my_sock,&active_fd_set);
printf(" Socket connected \n");
}
printf("Trying again \n\n\n");
}
--------------------------------------------------------------------
Upon running the server code following output is obtained repeatedly :
Socket created
Bind successful to the socket !!
Listening to socket
Couldn't connect to socket... will try later
Trying again
Socket created
Bind successful to the socket !!
Listening to socket
Couldn't connect to socket... will try later
Trying again
.
.
.
I have checked the path "/tmp/dsock" and the socket file "dsock" is there but looking inside the file shows:
"dsock" [Permission Denied]
A "stat dsock" of the file shows:
File: ‘dsock’
Size: 0 Blocks: 0 IO Block: 4096 socket
Device: 801h/2049d Inode: 1572866 Links: 1
Access: (0777/srwxrwxrwx) Uid: ( 7418/user) Gid: (25/group)
Access: 2017-08-31 17:16:29.569038461 -0600
Modify: 2017-08-31 17:16:29.569038461 -0600
Change: 2017-09-01 13:28:07.162071494 -0600
Birth: -
Can't find what the error is. The client side also shows similar connection error. Is it due to the UNIX domain socket file permission issues?
Upvotes: 1
Views: 2863
Reputation: 25
Now, I have implemented the server and client code appropriately as suggested by Gil Hamilton:
Server code:
int main(int argc, char *argv[])
{
/* Variable Definition */
int sockfd=-1, rem_addr_size;
struct sockaddr_un remote_addr;
chdir("/");
umask(0111);
/* Get the Socket file descriptor */
memset(&remote_addr, 0, sizeof(struct sockaddr_un));
if ((sockfd = socket(AF_LOCAL,SOCK_STREAM,0)) < 0)
{
printf("ERROR: Failed to obtain Socket Descriptor ! \n");
exit(1);
}
printf("Socket created \n");
/* Fill the socket address struct */
remote_addr.sun_family = AF_LOCAL;
strncpy(remote_addr.sun_path,"/tmp/dsock", strlen("/tmp/dsock")+1);
rem_addr_size=(offsetof(struct sockaddr_un, sun_path)
+strlen(remote_addr.sun_path)+1);
unlink(remote_addr.sun_path);
if(bind(sockfd ,(struct sockaddr *)&remote_addr,rem_addr_size)<0)
{ printf("BIND ERROR \n");
close(sockfd );
exit(1);
}
printf("Bind successful to socket !! \n");
if(listen(sockfd,16)==-1)
{ perror("Listen error !! \n");
printf("Listening error \n");
exit(-1);
}
printf("Listening to the socket \n");
int msgsock;
msgsock=accept(sockfd,0,0);
char* fs_name = "ts_data.dat";
char sdbuf[LENGTH];
printf("[Client] Sending %s to the Server... ", fs_name);
FILE *fs = fopen(fs_name, "r");
if(fs == NULL)
{
printf("ERROR: File %s not found.\n", fs_name);
exit(1);
}
printf("Success file found !! \n");
bzero(sdbuf, LENGTH);
int fs_block_sz;
if (msgsock == -1)
perror("Error in accepting socket connection \n");
else
while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs)) > 0)
{
if(send(sockfd, sdbuf, fs_block_sz, 0) < 0)
{
fprintf(stderr, "ERROR: Failed to send file %s. (errno =
%d)\n", fs_name, errno);
break;
}
bzero(sdbuf, LENGTH);
}
printf(" File %s to the client was Sent!\n", fs_name);
//}
close (sockfd);
printf("[Client] Connection lost.\n");
return (0);
}
Upon running the server code following output is seen:
Socket created
Bind successful to socket !!
Listening to the socket
Client code:
if(sock<0){
if ((sock=socket(AF_LOCAL,SOCK_STREAM,0))<0){
syslog(LOG_USER|LOG_ERR,"Could not create socket!!");
printf("Couldn't create socket \n");
exit(-1);
}
else
{
printf("Socket created \n");
}
/* Name the socket */
s_addr.sun_family = AF_LOCAL;
strncpy(s_addr.sun_path,sock_path,strlen(sock_path)+1);
s_addr_size=(offsetof(struct sockaddr_un, sun_path)
+strlen(s_addr.sun_path)+1);
/***************/
if(connect( sock,(struct sockaddr *) &s_addr,s_addr_size)==-1)
{
syslog(LOG_USER|LOG_ERR,"Could not connect, will try later");
printf("Error %d: %s\n", errno, strerror(errno));
printf("Couldn't connect to socket... will try later \n");
close(sock);
sock=-1;
}
else
{
FD_SET(sock,&active_fd_set);
printf("Socket connected \n");
}
printf("Trying again \n\n\n");
}
client gives the output:
Socket created
Couldn't connect to socket... will try later
Trying again
netstat -l shows the server in listening mode :
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ACC ] STREAM LISTENING 3294124420 /tmp/dsock
unix 2 [ ACC ] STREAM LISTENING 3294124858 /tmp/dsock
unix 2 [ ACC ] STREAM LISTENING 32778 /var/run/nslcd/socket
unix 2 [ ACC ] STREAM LISTENING 14365 /run/systemd/journal/stdout
unix 2 [ ACC ] STREAM LISTENING 612 /var/lib/gssproxy/default.sock
Have added the error logs in the codes as well, but the client doesn't connect to the socket.
Upvotes: 0
Reputation: 12337
You cannot call connect
on a listening socket. Once you have bound and listened, the only thing you should do with a listening socket is call accept
(or close
or use its descriptor in a select
).
So the server should create the socket, bind
its address, listen
on it and then the server should be sitting ("blocked") in the accept
function. That is, it's waiting for a connection, usually in a loop.
Then (after the server has been started and is waiting) your client needs to create its own socket and call connect
on it -- specifying the same address that the server used when it called bind
. This will cause the accept
call in the server to return a new socket descriptor for a socket that is actually connected to the client. This is the one that you will use send
and recv
on for communication. (And the client's socket will also be connected.)
At this point, the listening socket in the server will still be available to accept additional connections (each of which would return its own new unique socket descriptor).
Although possible, it doesn't really make sense for the server to connect to its own listening socket endpoint anyway. What would be the point?
Upvotes: 1