传递boost :: asio :: ip :: tcp :: socket

时间:2011-03-24 21:18:36

标签: c++ boost boost-asio

好的,这是我目前的代码段:

namespace bai = boost::asio::ip;
bai::tcp::socket tcp_connect(std::string hostname, std::string port) {
    try {
        boost::asio::io_service io_service;
        bai::tcp::resolver resolver(io_service);

        // we now try to get a list of endpoints to the server 
        bai::tcp::resolver::query query(hostname, port);
        bai::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
        bai::tcp::resolver::iterator end;

        // looking for a successful endpoint connection
        bai::tcp::socket socket(io_service);
        boost::system::error_code error = boost::asio::error::host_not_found;
        while (error && endpoint_iterator != end) {
            socket.close();
            socket.connect(*endpoint_iterator++ , error);
        }

        if (error) throw boost::system::system_error(error);

        return socket;
    } catch (std::exception &ex) {
        std::cout << "Exception: " << ex.what() << "\n";
    }
}

哪个应该boost::asio::ip::tcp::sockethostname port相关联。但是我遇到了一些难以理解的boost::noncopyable错误。但我的问题是,我该如何绕过这些插座呢?这有什么问题?

2 个答案:

答案 0 :(得分:13)

socket无法复制。请改用boost::shared_ptr<bai::tcp::socket>。如果您可以复制套接字,如果最终有两个代表相同底层操作系统套接字的socket个实例,那么您将遇到各种有趣的问题 - 因此复制是有意义的(因此<按值返回,按值传递)是不允许的。

答案 1 :(得分:3)

代码:

return socket;

尝试使socket的副本返回,然后在函数退出时销毁原始套接字。不幸的是,无法复制套接字(它们管理必须关闭的底层操作系统资源,因此系统必须确保只存在对该资源的一个引用,否则当第一个副本超出范围时会出现严重错误)。

正如在另一个答案中所建议的那样,你可以使用一个指针来返回在堆上创建的对象(应该使用shared_ptr进行管理,如果你只在一个地方使用unique_ptr,则更有效),或者如果您使用的是C ++ 11,则可以使用移动构造函数作为返回值:

return std::move (socket);

这将避免使用堆分配和指针的必要性,因此可能是更好的解决方案。