Ошибка имени файла сокета Unix

Это первый раз, когда я программирую с сокетами Unix, так что простите за глупые ошибки. Я написал следующую функцию для создания сокета Unix.

int create_server_unix_socket(const string& socket_path) {

// STEP 1 : socket()
int unix_socket = socket(AF_UNIX, SOCK_STREAM, 0);
if (unix_socket == -1) {
throw std::runtime_error {"Error occured in socket() call : "s +
string(std::strerror(errno))};
}

// STEP 2 : bind(), setup the address structures for bind()
sockaddr_un local_address;
local_address.sun_family = AF_UNIX;
std::strcpy(local_address.sun_path, socket_path.c_str());

// unlink from before
unlink(socket_path.c_str());

// STEP 2 : bind()
size_t length = socket_path.size() + sizeof(local_address.sun_family);
if (::bind(unix_socket, reinterpret_cast<sockaddr*>(&local_address),
length) == -1) {
throw std::runtime_error {"Error occured in bind() call : "s +
string(strerror(errno))};
}

// STEP 3 : listen()
if (listen(unix_socket, 5) == -1) {
throw std::runtime_error {"Error occured in listen() call : "s +
string(strerror(errno))};
}

return unix_socket;
}

Но всякий раз, когда я пытаюсь создать сокет, как это

create_server_unix_socket("./unix_socket"s);

Файл, который создается в текущем рабочем каталоге unix_socke вместо unix_socket и на самом деле это происходит с любым именем, которое я пытаюсь. Если я попробую unix_socket_longer_nameсозданный файл unix_socket_longer_nam, Я использую это на Mac OS X (версия 10.11.4).

Есть идеи, что я делаю не так? Также, если вы заметили что-то ужасно неправильное в моем коде, пожалуйста, дайте мне знать! Я написал это, просмотрев справочные страницы, и я не совсем уверен, что все сделал правильно. Спасибо!

НОТА : Я компилирую это с C ++ 14, вам нужно будет импортировать std::literals::string_literals пространство имен, чтобы сделать эту работу. добавлять using namespace std::literals::string_literals к началу вашего кода.

1

Решение

Давайте посмотрим на справочную страницу bind

int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);

Третий параметр addrlen

addrlen определяет размер в байтах адресной структуры, на которую указывает addr,

Итак, что вы должны пройти, это sizeof local_address, Вместо этого вы прошли length который socket_path.size() + sizeof(local_address.sun_family), Этого размера почти достаточно, но нет места для нулевого терминатора, и он игнорирует возможность того, что sockaddr_un может содержать отступы.

Если вы действительно хотите передать длину, которая соответствует пути, а не полный размер local_addressВы могли бы использовать offsetof:

length = offsetof(sockaddr_un, sun_path) + socket_path.size() + 1;

Но я не вижу преимущества перед простым прохождением sizeof local_address,

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]