c(gcc)centos 7中实现的unix域套接字中的连接错误

c(gcc)centos 7中实现的unix域套接字中的连接错误,c,linux,sockets,unix,gcc,C,Linux,Sockets,Unix,Gcc,在实现UNIX域套接字时,连接始终被拒绝: 部分服务器代码: 我已经检查了路径“/tmp/dsock”,套接字文件“dsock”在那里,但查看文件内部显示: "dsock" [Permission Denied] File: ‘dsock’ Size: 0 Blocks: 0 IO Block: 4096 socket Device: 801h/2049d Inode: 1572866 Links: 1

在实现UNIX域套接字时,连接始终被拒绝:

部分服务器代码: 我已经检查了路径“/tmp/dsock”,套接字文件“dsock”在那里,但查看文件内部显示:

    "dsock" [Permission Denied] 
      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: -
文件的“stat dsock”显示:

    "dsock" [Permission Denied] 
      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: -

找不到错误是什么。客户端也显示类似的连接错误。这是由于UNIX域套接字文件权限问题造成的吗?

您不能在侦听套接字上调用
connect
。绑定并侦听后,使用侦听套接字应该做的唯一一件事就是调用
accept
(或
close
,或在
选择中使用其描述符)

因此,服务器应该创建套接字,
bind
它的地址,
listen
,然后服务器应该坐在
accept
函数中(“阻塞”)。也就是说,它正在等待连接,通常是在循环中

然后(在服务器启动并等待之后),您的客户端需要创建自己的套接字并在其上调用
connect
——指定服务器调用
bind
时使用的相同地址。这将导致服务器中的
accept
调用为实际连接到客户端的套接字返回新的套接字描述符。这是您将用于通信的
send
recv
。(还将连接客户端的套接字。)

此时,服务器中的侦听套接字仍然可以接受其他连接(每个连接都将返回自己的新的唯一套接字描述符)


尽管有可能,但无论如何,服务器连接到自己的侦听套接字端点并没有真正意义。重点是什么?

现在,我已经按照Gil Hamilton的建议适当地实现了服务器和客户端代码:

服务器代码:

        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);
            }
            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");
}
客户端代码:

        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);
            }
            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");
}
netstat-l显示处于侦听模式的服务器:

   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

在代码中也添加了错误日志,但是客户端没有连接到套接字

解决此类问题的第一步始终是查看系统返回的错误。大多数UNIX系统调用将设置errno,以便在出错时返回-1时提供特定的错误详细信息。您应该:1)包括errno.h2)使用以下命令记录详细的错误消息:printf(“错误%d:%s\n”,errno,strerror(errno));理想情况下,这应该作为常规系统调用错误检查的一部分来完成