Обойти boost :: asio :: ip :: tcp :: socket - PullRequest
2 голосов
/ 25 марта 2011

Хорошо, это мой текущий фрагмент кода:

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::socket, подключенный к hostname на port. Однако я получаю кучу непонятных boost::noncopyable ошибок. Но мой вопрос: как мне тогда обойти эти розетки? Что с этим не так?

Ответы [ 2 ]

13 голосов
/ 25 марта 2011

socket не может быть скопировано. Вместо этого используйте boost::shared_ptr<bai::tcp::socket>. Если бы вы могли скопировать сокет, у вас возникли бы самые разные смешные проблемы, если бы у вас было два экземпляра socket, представляющих один и тот же базовый сокет ОС - поэтому имеет смысл копирование (и, следовательно, возврат по значению). , передача по значению) не допускается.

3 голосов
/ 11 января 2015

код:

return socket;

пытается создать копию сокета для возврата, а затем уничтожить исходный сокет при выходе из функции. К сожалению, сокеты не могут быть скопированы (они управляют базовым ресурсом операционной системы, который должен быть закрыт, поэтому система должна гарантировать, что существует только одна ссылка на этот ресурс, в противном случае все может пойти не так, если первая копия выйдет из области действия). *

Как предложено в другом ответе, вы можете использовать указатель для возврата объекта, созданного в куче (которым нужно управлять либо с помощью shared_ptr, либо более эффективно, если вы используете его только в одном месте unique_ptr), или если вы используете C ++ 11, вы можете использовать конструктор перемещения для возвращаемого значения:

return std::move (socket);

Это позволит избежать необходимости использовать выделение кучи и указатели, поэтому, вероятно, это предпочтительное решение.

...