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

时间:2012-04-10 13:50:26

标签: c sockets unix unix-socket

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

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

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

是否有人知道导致此行为的错误中的原因或位置?

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

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()");

我可能还值得注意的是,我使用getaddrinfo的修改版本专门为unix域填充addrinfo struct

1 个答案:

答案 0 :(得分:2)

在服务器启动之后,检查客户端系统上是否存在套接字文件,即确保您要在sun_path的{​​{1}}字段中使用的文件传入连接客户存在。此条目必须与在服务器中创建并传递到struct sockaddr_un的条目匹配。另外,请确保使用bind填充客户端和服务器中的sun_family字段。

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

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

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

  

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

然而,该段的最后一句陈述:

  

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

因此,在调用AI_PASSIVE的情况下逻辑稍微不正确,因为nodename参数不为null。