2012-06-12 35 views
5

Tôi có trình tạo bản sao đóng hộp gọi boost::asio::ip::tcp::resolver::resolve() trên localhost sau mỗi 5 giây. Nó đếm số điểm cuối được trả về và so sánh giá trị đó với lần lặp trước đó.kết quả từ trình phân giải Boost.Asio khác nhau

#include <boost/asio.hpp> 

#include <iostream> 

int main(int argc, char *argv[]) 
{ 
    if (argc < 3) { 
     std::cerr << argv[0] << " host port" << std::endl; 
     exit(EXIT_FAILURE); 
    } 
    const char* host = argv[1]; 
    const char* service = argv[2]; 

    boost::asio::io_service io_service; 
    boost::asio::ip::tcp::resolver resolver(io_service); 

    size_t previous = 0; 
    while (true) { 
     boost::asio::ip::tcp::resolver::iterator i(
       resolver.resolve(
        boost::asio::ip::tcp::resolver::query(host, service) 
        ) 
       ); 
     size_t count(0); 
     while (i != boost::asio::ip::tcp::resolver::iterator()) { 
      std::cout << i->endpoint() << std::endl; 
      ++i; 
      ++count; 
     } 

     std::cout << "got " << count << " addresses" << std::endl; 
     if (previous == 0) { 
      previous = count; 
     } 
     assert(count == previous); 

     sleep(5); 
    } 
} 

phiên mẫu

~> time ./addrinfo_asio localhost 80 

... 

127.0.0.1:80 
got 1 addresses 
[::1]:80 
127.0.0.1:80 
got 2 addresses 
addrinfo_asio: addrinfo_asio.cc:35: int main(int, char**): Assertion `count == previous' failed. 
Aborted (core dumped) 

real 216m20.515s 
user 0m0.181s 
sys  0m0.193s 
~> 

Bạn có thể nhìn thấy nó tìm thấy một thiết bị đầu cuối (127.0.0.1:80) trong khoảng 3,5 giờ, sau đó tìm thấy hai (127.0.0.1:80 và [:: 1] : 80). Tôi tự hỏi

  1. tại sao số điểm cuối thay đổi từ một đến hai?
  2. điều gì có thể gây ra?

Giải quyết cả địa chỉ ipv4 và ipv6 là cố ý, tôi không muốn giới hạn truy vấn chỉ ipv4. Tôi nhận ra hành vi này có khả năng không cụ thể với asio, tôi cũng có một trình sao chép gọi trực tiếp getaddrinfo thể hiện hành vi tương tự. Nền tảng của tôi là ppc64 RHEL 6.2 nếu nền tảng đó có liên quan. Tôi đã không cố gắng sao chép ở nơi khác.

+0

Địa chỉ ':: 1' là địa chỉ IPv6 localhost. Có thể mất quá nhiều thời gian để hệ điều hành nhận ra nó đã kích hoạt IPv6? –

+0

os bạn đang chạy là gì? – gda2004

+0

@ gda2004 xem câu cuối cùng của câu hỏi, ppc64 RHEL 6.2 –

Trả lời

3

Bạn có thể giới hạn phân giải chỉ IPv4:
ip :: tcp :: resolver :: truy vấn (ip :: tcp :: v4(), máy chủ, dịch vụ)

+1

AFAIU câu hỏi không phải là cách giới hạn địa chỉ được trả về bởi getaddrinfo, nhưng tại sao địa chỉ IPv6 xuất hiện sau một khoảng thời gian đã trôi qua. – Ralf

+0

Vâng, tôi đã được ấn tượng rằng chủ đề-starter đã không nhận thức được thực tế là truy vấn giải quyết của mình chứa cả ipv4 và ipv6, do đó, ông đã * không mong muốn * ipv6 truy vấn. Mặt khác, nó được biết rằng các truy vấn DNS ipv6 có thể rất chậm ... –

+0

@IgorR. Tôi biết địa chỉ ':: 1' là' ipv6-localhost', tôi đã chỉnh sửa câu hỏi của mình để phản ánh điều đó. Tôi không muốn giới hạn truy vấn giải quyết của mình chỉ với ipv4. –

1

Vâng Tôi không phải chuyên gia tăng , nhưng một trình duyệt nhanh cho tôi biết nó có vẻ là sử dụng AI_ADDRCONFIG theo mặc định (tốt, nó hầu như luôn luôn được sử dụng). Với cờ đó, nó sẽ chỉ trả lại địa chỉ IPv6 nếu bạn có ít nhất một địa chỉ IPv6 có thể định tuyến toàn cầu được định cấu hình. Có lẽ kết nối IPv6 của bạn không phải lúc nào cũng có sẵn?

+0

** Cảnh báo cụ thể của Windows: ** AI_ADDRCONFIG có thể khiến tra cứu cho máy chủ cục bộ bị lỗi. Xem [Tăng vé 8503] (https://svn.boost.org/trac/boost/ticket/8503) để biết chi tiết. –

Các vấn đề liên quan