使用Unix套接字时出现“地址已在使用中”的错误

10

使用Unix本地套接字编写以下C源代码时,我遇到了有关地址已在使用中的错误。在查看man 7 Unix获取更多信息后,我尝试创建一个子文件夹,在其中执行我的程序(显然修改当前文件夹上的sun_path字段),但错误仍然相同。

有人能帮帮我吗?

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>

#define MAXLEN  128

int main (int argc, char *argv[]){

        struct sockaddr_un      server;
        int                                     serverfd, clientfd;
        socklen_t                       addrsize = sizeof(struct sockaddr_un);
        char                            buff[MAXLEN], *path;

        if (argc < 2){
                printf("Error: %s [MESSAGE]\n", argv[0]);
                return 1;
        }

        if ((serverfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
                printf("Error \"%s\" in socket()\n", strerror(errno));
                exit(1);
        }
        puts("socket()");

        server.sun_family = AF_UNIX;
        path = strcpy(server.sun_path, "/home/myhome/Dropbox/Sources/C/sub");

        printf("[DEBUG]Address bound at %s\n", path);

        if ((bind(serverfd, (struct sockaddr*)&server, addrsize)) < 0){
                printf("Error \"%s\" in bind()\n", strerror(errno));
                exit(1);
        }
        puts("bind()");


        if ((listen(serverfd, 1)) < 0){
                printf("Error \"%s\" in listen()\n", strerror(errno));
                exit(1);
        }

        if ((clientfd = accept(serverfd, NULL, &addrsize)) < 0){
                printf("Error \"%s\" in accept()\n", strerror(errno));
                exit(1);
        }

        write(clientfd, argv[1], strlen(argv[1]));
        read(clientfd, buff, sizeof(buff));

        puts(buff);

        close(clientfd);
        close(serverfd);
        return 0;
}

请提供您所看到的精确错误信息。 - xaxxon
显示的错误是: “在绑定()中出现“地址已在使用中”的错误” - Acsor
嘿,不要在AF_UNIX中使用Dropbox文件系统。它真的需要是本地文件系统。你可以在谷歌上搜索为什么。这里有风险,所以除非你在本地文件系统上尝试并重现它,否则我认为没有人能帮助你。 - xaxxon
1
另外,你是否确保在存在文件的情况下取消链接该文件?http://beej.us/guide/bgipc/output/html/multipage/unixsock.html - xaxxon
刚试了一下把程序移到家里,结果连个屁都不响。 我要去读那个页面。 - Acsor
显示剩余2条评论
2个回答

25

在调用bind之前,您应该使用unlink()函数删除path文件,否则会在bind期间出现文件已存在的错误。因此,在退出应用程序之前,请确保删除文件或者始终在bind之前删除它。

请查看bind的手册页。另外,请注意手册页末尾给出的示例。


1
是的,我也刚看到这个。 - xaxxon
是的,我刚试过了,它可以工作。 无论如何,感谢两位和+1给xaxxon。 - Acsor

-4
您可以尝试使用SO_REUSEADDR标志,如下所示:
int yes = 1;
if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    // error handling
    exit(1);
}

我读到一些东西,虽然它没有明确定义这对非网络协议没有意义。 - xaxxon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接