Unix套接字文件名错误

时间:2016-05-03 09:13:09

标签: c++ sockets unix c++14 unix-socket

这是我第一次使用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 个答案:

答案 0 :(得分:2)

让我们来看看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)。这个大小已经足够了,但是null终结符没有空间,它忽略了sockaddr_un可能包含填充的可能性。

如果您确实希望传递与路径匹配的长度而不是local_address的完整尺寸,则可以使用offsetof

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

但是,仅仅通过sizeof local_address,我就没有看到它的优势。