ECONNREFUSED на датаграмме Unix сокет

0

Каковы возможные причины ECONNREFUSED при отправке через Unix сокета без установления соединения?

Также приветствуются любые рекомендации о том, как отлаживать это, поскольку эта проблема воспроизводима.

Я получаю ошибку независимо от того, используется ли 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
  • 0
    Эх, целевой сокет не существует?
  • 0
    Это существует. Я отредактировал код в вопросе, чтобы показать, что клиент отправляет сообщение и recvfrom работает, как ожидалось. Клиентское приложение застряло в recv() (я могу там установить recv() останова)
Показать ещё 6 комментариев
Теги:
sockets
unix-socket

1 ответ

1
Лучший ответ

От man 7 unix:

ECONNREFUSED Удаленный адрес, указанный подключением (2), не является гнездом для прослушивания. Эта ошибка также может возникать, если целевое имя файла не является сокетом.

В Linux sendto на Unix-сокет делает следующее:

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         }

Другими словами, на другом конце сокета, который вы отправляете, нет читателя, или сокет больше не существует в файловой системе.

  • 0
    Ну, у меня есть сокет на другой стороне (на стороне клиента), привязка работала нормально. Я даже могу отправлять вещи с клиента и получать с recvfrom на сервере.
  • 0
    @ Джордж Ваш клиент может быть прерван после отправки.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню