好的,这是我目前的代码段:
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
错误。但我的问题是,我该如何绕过这些插座呢?这有什么问题?
答案 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);
这将避免使用堆分配和指针的必要性,因此可能是更好的解决方案。