首页 文章

Unix域套接字(C) - 客户端“删除”connect()上的套接字?

提问于
浏览
0

这可能有点难以简洁地列举,但我将尽我所能了解域和问题 .

我有2个进程,一个流服务器首先取消链接,创建套接字描述符,绑定,侦听和接受本地unix套接字 . 服务器的工作是接受连接,发送任意数据,并接收任意数据 . 除初始设置外,客户端进程的工作与服务器相同;创建套接字描述符,并连接到unix套接字 .

启动服务器后,我可以验证是否正在创建unix套接字 . 启动客户端后,收到 connect() 错误,指出文件或目录不存在或无效 . 是的,尝试像以前一样找到unix套接字,文件不再存在......

有谁知道导致这种行为的bug中可能存在的原因或位置?

如果代码片段有助于澄清,我当然也可以发布这些代码片段 .

struct addrinfo * server;
int sockfd;

sockfd = socket( server->ai_family, server->ai_socktype, server->ai_protocol );

if( connect(sockfd, server->ai_addr, server->ai_addrlen) == 0 )
    return sockfd;
else
    perror("connect()");

它's probably also worth noting that I' m使用 getaddrinfo 的修改版本专门为unix域填充 addrinfo struct .

1 回答

  • 2

    在服务器启动之后,检查客户端系统上是否存在套接字文件,即确保将要在 struct sockaddr_unsun_path 字段中使用的文件传递到客户端上的连接中 . 此条目必须与在服务器中创建并传入 bind 的条目匹配 . 还要确保使用 AF_UNIX 填充客户端和服务器中的 sun_family 字段 .

    在客户端中不执行任何套接字文件的创建/删除 - 即在客户端代码中的任何位置都不应该与服务器套接字的位置相关联 .

    这些是我将遵循的一般过程,以确保代码做正确的事情 . 旧版中有一个示例服务器/客户端,但仍然可靠Beej's guide to UNIX IPC,这可能是您应该比较的最简单的示例 .

    Edit 根据评论中的讨论,事实证明自定义 getaddrinfo 调用是删除unix套接字文件的罪魁祸首 . 这是因为代码中存在服务器端逻辑,用于检查是否设置了 hints->ai_flags & AI_PASSIVE . 如果是这种情况,那么它取消链接套接字文件,因为它期望软件执行 bind (如在服务器中) . 有关 AI_PASSIVE 标志的逻辑在the RFC中编码,在这种情况下,如果文件不存在,绑定将失败 .

    如果指定了AI_PASSIVE标志,则返回的地址信息应适合用于绑定套接字以接受指定服务的传入连接(即调用bind()) .

    但是,该段的最后一句规定:

    如果nodename参数不为null,则忽略此标志

    因此,在调用 getaddrinfo( "/local", "/tmp/socket", hints, &server) 的情况下,似乎逻辑稍微不正确,因为nodename参数不为null .

相关问题