【问题标题】:ECONNREFUSED on datagram Unix socket数据报 Unix 套接字上的 ECONNREFUSED
【发布时间】:2014-11-18 21:42:52
【问题描述】:

通过无连接数据报 Unix 套接字发送时,ECONNREFUSED 的可能原因是什么?

也欢迎任何有关如何调试此问题的建议,因为此问题是可重现的。

无论使用sendto()sendmsg(),我都会收到错误消息。

if ((sock = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0)
{
    return 0;
}
unlink("/tmp/serv");
addr.sun_family = AF_UNIX;    

strncpy(&addr.sun_path[0], "/tmp/serv", sizeof(addr.sun_path));

if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
    return 0;
}

sockaddr_un from;
int fromlen = sizeof(from);
if (recvfrom(sock, &i, sizeof(i),0,(sockaddr*)&from,(socklen_t*)&fromlen) < 0 )
{
    //some error handling code
}

printf("from.sun_family=%d, from.sun_path=%s",from.sun_family,from.sun_path); // this prints, as expected "from.sun_family=1, from.sun_path=/tmp/client"
strncpy(&addr.sun_path[0], "/tmp/client", sizeof(addr.sun_path));
sendto(sock,"abc",3,0,(sockaddr*)&addr, sizeof(addr)); //this fails with ECONNREFUSED

【问题讨论】:

  • Err,目标socket不存在?
  • 它存在。我编辑了问题中的代码以显示客户端发送消息并且recvfrom 按预期工作。客户端应用程序卡在recv()(我可以在那里断点)
  • @George which call in your code is given you ECONNREFUSED ?
  • @nos sendto(sock,"abc",3,0,(sockaddr*)&addr, sizeof(addr));
  • 发布最小可编译和可运行的客户端和服务器。在准备这些时,您很可能会发现错误。

标签: c++ sockets unix unix-socket


【解决方案1】:

来自man 7 unix

ECONNREFUSED connect(2) 指定的远程地址不是侦听套接字。 如果目标文件名不是套接字,也会发生此错误。

在 Linux 中,sendto 在 Unix 套接字上 does the following

1548         if (sock_flag(other, SOCK_DEAD)) {
1549                 /*
1550                  *      Check with 1003.1g - what should
1551                  *      datagram error
1552                  */
1553                 unix_state_unlock(other);
1554                 sock_put(other);
1555 
1556                 err = 0;
1557                 unix_state_lock(sk);
1558                 if (unix_peer(sk) == other) {
1559                         unix_peer(sk) = NULL;
1560                         unix_state_unlock(sk);
1561 
1562                         unix_dgram_disconnected(sk, other);
1563                         sock_put(other);
1564                         err = -ECONNREFUSED;
1565                 } else {
1566                         unix_state_unlock(sk);
1567                 }
1568 
1569                 other = NULL;
1570                 if (err)
1571                         goto out_free;
1572                 goto restart;
1573         }

换句话说,您发送到的套接字的另一端没有读取器,或者该套接字不再存在于文件系统中。

【讨论】:

  • 好吧,我在另一边(客户端)有一个套接字,绑定工作正常。我什至可以从客户端发送东西并在服务器上使用 recvfrom 接收。
  • @George 您的客户端可能在发送后已终止。
  • 恐怕不行,客户端有一些非常简单的代码,用sendto()发送后它在recv()等待。
  • 正如我所说,问题是 100% 可重现的,因此我删除了所有不必要的代码。 sendto() 真的发送“abc”。在客户端,我真的只有一个 sendto() 一个 setsockopt() 设置 5 秒超时和一个 recv()
  • @George 正确的方法是确保套接字没有关闭,特别是如果它是您提到的简单代码。在 gdb 下运行您的客户端,在 closeshutdown 上设置断点,然后查看您的套接字调用它的内容。
猜你喜欢
  • 1970-01-01
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多