2017-10-05 1 views
1

몇 시간 동안 문제가 있습니다. 부스트 asio udo 소켓을 엔드 포인트에 연결하고 싶습니다. IPv4에서이 작업을 수행하는 데 아무런 문제가 없습니다. 그러나 IPv6에서 동일한 작업을 수행하려고하면 "잘못된 인수"라는 오류 코드가 표시됩니다.boost asio udp socket connect (IPv6)에 잘못된 인수가 있습니다.

using boost::asio::ip::udp; 

struct UdpConnectionParams 
{ 
    udp::endpoint m_localEndpoint; 
    udp::endpoint m_remoteEndpoint; 
} 

boost::system::error_code setupUdpConnection(udp::socket& p_socket, const UdpConnectionParams& p_params) 
{ 
    // close socket 
    boost::system::error_code h_ignoreError; 
    p_socket.close(h_ignoreError); 
    // variables for kind of UDP connection 
    udp h_protocol(udp::v4()); 
    bool h_shallBind{false}; 
    bool h_shallConnect{false}; 

    // determine kind of connection 
    if(p_params.m_localEndpoint != udp::endpoint()) 
    { 
     h_protocol = p_params.m_localEndpoint.protocol(); 
     h_shallBind = true; 
    } 
    if(p_params.m_remoteEndpoint != udp::endpoint()) 
    { 
     h_protocol = p_params.m_remoteEndpoint.protocol(); 
     h_shallConnect = true; 
    } 
    if(!h_shallBind && !h_shallConnect) 
    { 
     // no endpoint specified, return error 
     return boost::system::error_code(ENetworkErrorCode::NO_ENDPOINT_SPECIFIED, NetworkErrorCategory::getCategory()); 
    } 

    try 
    { 
     p_socket.open(h_protocol); 
     //bind socket to certain endpoint 
     if(h_shallBind) 
     { 
      p_socket.bind(p_params.m_localEndpoint); 
     } 
     //connect socket to client. Thus it is possible to use p_socket.send() 
     if(h_shallConnect) 
     { 
      p_socket.connect(p_params.m_remoteEndpoint); 
     } 
    } 
    catch (boost::system::system_error& h_error) 
    { 
     p_socket.close(h_ignoreError); 
     return h_error.code(); 
    } 
    // no error 
    return boost::system::error_code(); 
} 

int main() 
{ 
    boost::asio::io_service service; 
    udp::socket socket(service); 
    boost::system::error_code error; 
    UdpConnectionParams params; 
    params.m_localEndpoint = udp::endpoint(udp::v6(), 55555); 
    params.m_remoteEndpoint = udp::endpoint(boost::asio::ip::address_v6::from_string("ff01::101"), 55555); 
    error = setupUdpConnection(socket, params); 
    cout << error << error.message() << endl; // "invalid argument" 
    return 0; 
} 

오류가 발생하는 유일한 방법은 로컬 호스트 IP 주소 (:: 1)입니다. 소켓을 끝점에 바인딩해도 아무런 차이가 없습니다. 내가 뭘 잘못하고 있니?

답변

2

내가 뭘 잘못하고 있니?

문제는 사용중인 IPv6 주소에 인터페이스 색인/범위를 지정하지 않았기 때문입니다. IPv6 멀티 캐스트 주소는 범위를 지정해야하므로 네트워크 스택이 IP 주소를 연결할 컴퓨터의 로컬 네트워크 인터페이스를 알 수 있습니다.

즉, 대신 : 물론, 당신이 사용할 네트워크 인터페이스의 이름에 따라 달라집니다 % 기호 후

boost::asio::ip::address_v6::from_string("ff01::101%eth0"), 55555); 

(접미사 :

boost::asio::ip::address_v6::from_string("ff01::101"), 55555); 

당신이 뭔가를 필요)

(부수적으로, "ff01 ::"접두어는 노드 로컬 IPv6 멀티 캐스트 그룹을 나타냅니다. 즉, UDP 패킷은 동일한 컴퓨터에서 실행되는 다른 프로그램으로 만 이동합니다. 당신이 의도 한 것, 그 다음에는 위대한 것입니다; 반면에 UDP 패킷이 같은 LAN에있는 다른 컴퓨터에 도달하게하려면 대신 "ff02 ::"또는 "ff12 ::"접두사를 사용하고 싶을 것입니다 (ff02 :: well- 알려진 멀티 캐스트 주소, ff12 ::은 일시적인 멀티 캐스트 주소 일 것입니다. 자세한 내용은 the Wikipedia page의 "멀티 캐스트 주소 범위"표를 참조하십시오.

+0

고맙습니다! 음, "ff01 :: 101 % eth0"또는 "ff01 :: 101 % lo"로는 작동하지 않지만 "ff12 :: 1 % eth0"와 작동합니다. 노드 로컬 IPv6 멀티 캐스트 그룹에 소켓을 연결하려면 무엇이 필요합니까? 소켓을 연결하지 않고 대신 "send_to"및 "receive_from"메서드를 사용하면이 문제가 발생하지 않습니까? – Christi258

+0

ff11 :: 1 % eth0 (또는 ff11 :: 11 % lo 등)이 노드 로컬 해당 그룹입니다. send_to() 및 receive_from()에서는 작동하지만 connect()에서는 작동하지 않는 이유는 알 수 없습니다. –

관련 문제