как указано в заголовке, мой вызов connect() к сокету типа домена unix с соответствующим адресом приводит к ошибке ENOENT: нет такого файла или каталога.
Два сокета правильно инициализированы, и файлы сокетов созданы и привязаны соответствующим образом. Серверные и клиентские сокеты выполняются в разных процессах, хотя клиентский процесс обрабатывается fork() и execl(). Точно так же я анализирую адрес клиентского и серверного сокетов, которые я использую для настройки клиентского сокета. Серверный процесс использует pthreads.
Вот моя попытка connect():
struct sockaddr_un address;
address.sun_family = AF_UNIX;
memcpy(address.sun_path, filepath.c_str(), filepath.length());
address.sun_path[filepath.length()] = '\0';
if(-1 == connect(this->unix_domain_descriptor_.descriptor(), \
(struct sockaddr*)&address, \
size))
{
global::ExitDebug(-1, "connect() failed", __FILE__, __LINE__);
return -1;
}
Я пробовал разные значения размера, например:
// this is from unix(7) man page. It doesn't work neither with nor without "+1"
socklen_t size = offsetof(struct sockaddr_un, sun_path);
size += strlen(address.sun_path) + 1;
// this is from one of my books about linux programming
socklen_t size = sizeof(address);
// this is from a sample code which I found at the internet
socklen_t size = sizeof(address.sun_family) + strlen(address.sun_path);
// Update 1:
socklen_t size = SUN_LEN(&address);
// this is what I tried out after looking into the declaration
// of struct sockaddr_un
socklen_t size = strlen(address.sun_path);
Удивительно, но все инициализации, кроме последней, приводят к ошибке EINVAL: недопустимый аргумент для connect(), и я получаю ENOENT: нет такого файла или каталога strong> только с последним. Я даже пробовал целые примеры из Интернета, но безуспешно. И очевидно, что замена socklen_t на size_t или int ничего не меняет.
Я уже проверил это:
- address.sun_path содержит правильный путь к файлу сокета, начиная с корневого каталога
- address.sun_path имеет длину 61 символ.
- address.sun_family имеет значение AF_UNIX/AF_LOCAL.
- address.sun_family имеет размер 2 байта
- нет ошибок при создании и привязке обоих сокетов
- серверный сокет находится в состоянии прослушивания
- sizeof(address) возвращает 110, как и должно быть
Теперь мне было интересно, почему не работает пример man-страницы и были ли изменения, которые не были обновлены на linux.die.net или www.kernel.org а>. Моя ОС — Debian Squeeze, если это актуально.
Любые идеи, что я делаю неправильно? И как это решить? Если вам нужно больше кода или у вас есть вопросы, то не стесняйтесь спрашивать меня (хотя, вероятно, мне не нужно это заявлять, но это мой первый пост здесь >.‹).
кстати, извините за мой плохой английский
Обновление 2
Решено. Я опубликую это в дополнительном ответе ниже из ясности.
strcpy
вместоmemcpy
и ручного размещения нулевого терминатора? - person Jonathon Reinhart   schedule 24.07.2012strace
клиент, посмотреть, не напечатает ли он что-нибудь неожиданное во времяconnect
. Однако это выстрел в темноте. - person MvG   schedule 24.07.2012