0

简明扼要地列举这可能有点困难,但我会尽我所能对领域和问题的新手理解。

我有 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来专门填充addrinfo structunix 域。

4

1 回答 1

2

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

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

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

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

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

但是,该段的最后一句指出:

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

因此,在这种 call 的情况下,逻辑似乎有点不正确getaddrinfo( "/local", "/tmp/socket", hints, &server),因为 nodename 参数不为空。

于 2012-04-10T14:15:39.617 回答