Boost Android Asio 连接错误

Posted

技术标签:

【中文标题】Boost Android Asio 连接错误【英文标题】:Boost Android Asio Connection Error 【发布时间】:2014-02-14 23:05:22 【问题描述】:

我正在使用 Boost Asio 进行跨平台网络。我尝试了各种连接方法,但在尝试连接到 android 上的套接字时,我不断收到“找不到元素”asio.misc 错误。我很困惑,因为这发生在成功解析域名之后。例如,如果我为主机和端口 80 输入 google.com,那么解析器将打印出所有 20 多个谷歌服务器,但稍后它不会连接说 asio.misc “找不到元素”

这是我的代码:

    boost::asio::io_service service;
    boost::system::error_code ec;
    boost::asio::ip::tcp::resolver resolver(service);
    boost::asio::ip::tcp::resolver::query query(host, port);
    boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(query, ec);
    boost::asio::ip::tcp::resolver::iterator iterEnd;
    boost::asio::ip::tcp::endpoint ep;
    int it = 0;
    while(iter != iterEnd)
    
        ep = *iter++;
        debug+="\nLooking at resolve with address " + ep.address().to_string();
        it++;
    

        //Try to connect through asio
        boost::asio::ip::tcp::socket sock( service );
        //asio::connect does all the iterator work for us.
        boost::asio::connect(sock, iter, ec);

        if( ec )
        
            return new string("Should be connected but I can't");
        
        else
        
            debug+= "\n     " + ec.message() + "\n     " + ec.category().name();
            return debug;
        

【问题讨论】:

您是否拥有访问互联网所需的权限? 是的,我愿意。它将域名解析为正确的 IP 地址,所以我知道我设置了它。 你怎么打电话给servicepost()bind(). 【参考方案1】:

调试循环耗尽了迭代器,导致boost::asio::connect() 被一个结束迭代器调用。

boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(query, ec);

while(iter != iterEnd) // iterate to exhaustion

  ep = *iter++;
  // ...      


// ...
boost::asio::connect(sock, iter, ec); // use exhausted iterator

要解决此问题,请考虑在通过更改构建调试信息时迭代 iter 的副本:

while(iter != iterEnd)

  ep = *iter++;
  // ...      

到:

for(tcp::resolver::iterator i = iter, end; i != end; ++i)

   ep = *i;
   // ...


这是一个大致基于原始代码的完整示例,用于演示差异:

#include <iostream>
#include <boost/asio.hpp>

void connect(const char* address, const char* port, bool exhaust)

  using boost::asio::ip::tcp;

  boost::asio::io_service io_service;
  tcp::resolver resolver(io_service);
  tcp::resolver::iterator iterator = resolver.resolve(
      tcp::resolver::query(address, port));

  // If flag is set, exhaust the iterator. 
  if (exhaust)
  
    std::cout << "Exhausting iterator" << std::endl;
    for (tcp::resolver::iterator end; iterator != end; ++iterator) 
  
  // Otherwise, exhaust a copy of the iterator.
  else
  
    std::cout << "Exhausting copy of iterator" << std::endl;
    for (tcp::resolver::iterator i = iterator, end; i != end; ++i) 
  

  tcp::socket socket(io_service);
  boost::system::error_code error;
  connect(socket, iterator, error);
  std::cout << error.category().name() << " -- " 
            << error.message() << std::endl;


int main()

  connect("google.com", "80", true);  // exhaust
  connect("google.com", "80", false); // do not exhaust

产生以下输出:

Exhausting iterator
asio.misc -- Element not found
Exhausting copy of iterator
system -- Success

【讨论】:

那行得通,以这种方式迭代看起来很奇怪,但它在他们的网站上,在几个参考中,并且在 iOS 中有效。谢谢!

以上是关于Boost Android Asio 连接错误的主要内容,如果未能解决你的问题,请参考以下文章

boost::asio 无法干净地关闭 TCP 连接

C++ boost::asio 无法建立连接,因为目标机器主动拒绝它

如何在 Boost.ASIO 中分配已连接的本机套接字类型 (TCP)

boost::asio - 知道何时必须关闭/关闭连接

为啥在使用 boost::asio 时每个连接都需要 strand?

boost::asio::acceptor - 在旧连接仍然打开时接受新的传入连接