Met_radar_Novice
Met_radar_Novice

Reputation: 25

connection error in unix domain socket implemented in c (gcc) centos 7

In implementing a UNIX domain socket the connection is always refused:

Part of Server Code:

    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

Answers (2)

Met_radar_Novice
Met_radar_Novice

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

Gil Hamilton
Gil Hamilton

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

Related Questions