2012-04-10 33 views
0

这可能有点难以简单列举,但我会尽我所能对新手理解域和问题。Unix域套接字(C) - 客户端“删除”connect()上的套接字?

我有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中结构。

+1

连接设置的代码应该有所帮助。 – twain249 2012-04-10 13:52:45

+0

你是如何设置'server struct'的?你还使用什么端口和IP地址? – twain249 2012-04-10 14:05:15

+0

'addrinfo struct'由修改后的getaddrinfo(“\ local”,“\ tmp \ socket”,提示和服务器)API处理,以处理unix域套接字。 – 5k1zk17 2012-04-10 14:23:04

回答

2

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

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

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

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

如果指定了AI_PASSIVE标志,则返回地址信息 应适合于在结合的插座接受传入 连接为指定的服务使用(即,呼叫结合())。

然而,第二款规定的最后一句:

这个标志,如果节点名称参数不是null

因此它似乎逻辑在这个略显不正确忽略因为nodename参数不为null,所以请致电getaddrinfo("/local", "/tmp/socket", hints, &server)

+0

感谢您的评论,我彻底检查了错误的unlink语句的客户端代码。没有绑定被调用,我认为是什么在系统上创建实际的套接字文件。 – 5k1zk17 2012-04-10 14:21:12

+0

验证:客户端中的''socket'调用确认:'ai_family == AF_UNIX','af_socktype == SOCK_STREAM'和'ai_protocol == 0',并且server-> ai_addr是有效的sockaddr_un结构 - 即sun_family对应于'AF_UNIX','sun_path'包含文件的名称(在返回时没有尾随NULL)。并且请告诉我你在路径名中没有使用\,它应该是'“/ tmp/socket”',否则'“\ t”'会被解释为标签 – Petesh 2012-04-10 14:57:19

+0

哈哈 - 对于上面的错字,是的,unix路径是正斜杠,“/ tmp/socket – 5k1zk17 2012-04-10 15:21:39