У меня есть странная проблема с сокетом unix (США) с использованием так называемых абстрактных пространств имен при использовании Python и «чистого» C (Python 3.x, но похоже, что 2.x имеет ту же проблему). «Нормальная» розетка работает как шарм. С «абстрактным» одним США мой код работает только тогда, когда я использую ту же «кодовую платформу» (C или Python).
Сначала я подумал, что это как-то связано с memset
/str(n)cpy
(см. Не удается подключиться к абстрактному сокету unix в python), но имхо это не тот случай.
Тестовая матрица (srv — сервер, cli — клиент):
- srv + cli @ "abstract" unix sock:
- python + python = OK
- c + c = OK
- srv + cli @ "normal" unix sock:
- python + python = OK
- c + c = OK
- srv + cli @ "normal" unix sock:
- python + c = OK
- с + питон = ОК
- srv + cli @ "abstract" unix sock:
- python + c = FAIL [cli / strace output: ECONNREFUSED (Connection refused)]
- c + python = FAIL [cli / подняло исключение: socket.error: [Errno 111] В соединении отказано]
/proc/net/unix
/ lsof
или strace
ничего необычного не показывают:
работающий "обычный" клиент сокета C:
// ...
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_LOCAL, sun_path=@"/var/tmp/sock.tmp"}, 110) = 0
// ...
неправильное поведение "абстрактного" клиента сокета C:
// ...
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_LOCAL, sun_path=@"/var/tmp/sock.tmp"}, 110) = -1 ECONNREFUSED (Connection refused)
// ...
Ошибка Python или что...?
Суть с примерами кода для моей тестовой матрицы: https://gist.github.com/soutys/ffbe2e76a86835a9cc6b
Исходный код/образцы:
- C-серверы/клиенты — на основе https://github.com/troydhanson/network/tree/master/unixdomain
- Серверы/клиенты Python — на основе примера сокета Python 3.X Unix
Обновление 2015-11-02
Подробнее о системе и компиляциях:
- хост-система: Ubuntu 14.04.3 LTS (x64);
- все тестовые файлы C, скомпилированные с
gcc
(пример:gcc -Wall -Wextra -pedantic -o abs_cli abs_cli.c
); - все программы (как скомпилированные, так и встроенные на python) запускаются от имени пользователя без полномочий root;
#include <string.h>
для системных функций:memset()
иstrncpy()
. Всегда включайте все предупреждения при компиляции, а затем исправьте эти предупреждения. (для gcc при минимальном использовании:-Wall -Wextra -pedantic
) - person user3629249   schedule 01.11.2015-Wall
, так и с-Wall -Wextra -pedantic
... хорошо - я добавил записи заголовка string.h для ясности. - person soutys   schedule 02.11.2015strncpy(&addr.sun_path[1], socket_path, sizeof(addr.sun_path) - 2);
есть сдвиг, который дает правильное смещение в структуре с нулями. - person soutys   schedule 02.11.2015