2011-12-21 13 views
5

मैंने सोचा कि मुझे निम्नलिखित उदाहरण में जवाब मिला है, लेकिन काफी नहीं।एक विशिष्ट ईथरनेट इंटरफेस को एएसओ सॉकेट मल्टीकास्ट को बढ़ावा दें

boost::asio::ip::udp::socket socket(io_service); 
... 
boost::asio::ip::address_v4 local_interface = 
    boost::asio::ip::address_v4::from_string("1.2.3.4"); 
boost::asio::ip::multicast::outbound_interface option(local_interface); 
socket.set_option(option); 

मैं कैसे नक्शा उचित outbound_interface विकल्प को eth0 करते हैं?

+0

सकता है वहाँ अपनी पोस्ट पर स्वरूपण जाँच करना चाहते हैं ... –

उत्तर

0

निम्नलिखित कोड विंडोज और मैक ओएस एक्स पर ठीक काम करता है:

const ip::udp::resolver::query queryIF(ip::udp::v4(),     
             _description->getInterface(), "0"); 
    const ip::udp::resolver::iterator interfaceIP =       
     resolver.resolve(queryIF);           

    if(interfaceIP == end)             
     return false;               

    const ip::address ifAddr(ip::udp::endpoint(*interfaceIP).address()); 

    _read->set_option(ip::multicast::join_group(mcAddr.to_v4(),    
                ifAddr.to_v4()));   
    _write->set_option(ip::multicast::outbound_interface(ifAddr.to_v4())); 

संपादित करें: मैं लिनक्स पर कुछ मुद्दों पर था, लेकिन इसे में अभी तक मुड़कर नहीं देखा। मेरा अनुमान है कि सॉकेट विकल्प को रूटिंग टेबल के पक्ष में अनदेखा किया जाता है।

+5

'_read',' _write', '_descriptor' आदि क्या हैं? – example

0

मुझे लगता है कि आपका उदाहरण और ईइल का उदाहरण क्यों काम नहीं करता है क्योंकि आपने SO_BINDTODEVICE सॉकेट विकल्प सेट नहीं किया है। क्यों यह काम नहीं करता

इस देखें पता करने के लिए: http://codingrelic.geekhold.com/2009/10/code-snippet-sobindtodevice.html

देखें इस पता है कि कैसे बढ़ावा :: asio के साथ यह करने के लिए: http://permalink.gmane.org/gmane.comp.lib.boost.asio.user/2724

0
/**************************************************************************//** 
\brief  
\details  
*******************************************************************************/ 
class UDPClient : public BoostSocketClient 
{ 
public: 
    UDPClient(); 
    virtual ~UDPClient(); 
    virtual ARLErrorCode_e open(int port_num, const char* network_type="ipv4", const char* ip_address="", uint32_t listen_interface=0); 
    virtual ARLErrorCode_e send(u8* message, u32 size); 
    virtual ARLErrorCode_e close(); 
    virtual bool isOpen(); 
    //virtual void onReceived(u8*, u32); 

private: 
    void startReceive(); 
    void handleReceive(const boost::system::error_code&, std::size_t); 
    void handleSend(const boost::system::error_code& error, std::size_t bytes_transferred); 

private: 
    boost::asio::io_service send_ios_; 
    std::unique_ptr<boost::asio::io_service::work> send_worker_; 

    boost::asio::io_service receive_ios_; 
    std::unique_ptr<boost::asio::io_service::work> receive_worker_; 

    boost::thread send_thread_; 
    boost::thread receive_thread_; 
    boost::array<u8, 1024> _buffer; 
    boost::asio::ip::udp::endpoint send_endpoint_; 
    boost::asio::ip::udp::endpoint sender_endpoint_; 
    boost::asio::ip::udp::endpoint listen_endpoint_; 

    std::unique_ptr<boost::asio::ip::udp::socket> send_udp_socket_; 
    std::unique_ptr<boost::asio::ip::udp::socket> receive_udp_socket_; 

}; 


#include <ACCompLib/Include/Typedefs.h> 
#include <ACCompLib/Include/ARLErrorCodes.h> 
#include <NetLib/Platform/Boost/cpp/UDPClient.h> 
#include "Ws2tcpip.h" 
#include "Iphlpapi.h" 


using namespace std; 
using namespace boost; 
using namespace asio; 
using namespace ip; 
using namespace NetLib; 

/***************************************************************************//** 
\brief   Constructor 
\details   

*******************************************************************************/ 
UDPClient::UDPClient() 
{ 
    receive_worker_.reset(new boost::asio::io_service::work(receive_ios_)); 
} 
/***************************************************************************//** 
\brief   ctor 
\details   
*******************************************************************************/ 
UDPClient::~UDPClient() 
{ 
    try 
    { 
     receive_worker_.reset(); 
     //send_worker_.reset(); 
     if (send_thread_.joinable()) { 
      send_thread_.join(); 
     } 
     if (receive_thread_.joinable()) { 
      receive_thread_.join(); 
     } 
    } 
    catch (std::exception& e) 
    { 
     std::string str = e.what(); 
    } 
} 

/***************************************************************************//** 
\brief   
\details   
\note   
\param[in]  
*******************************************************************************/ 
ARLErrorCode_e UDPClient::open(int port_num, const char* network_type, const char* multicastAddress, uint32_t listen_interface) 
{ 
    try 
    { 
     struct in_addr in; 
     in.S_un.S_addr = listen_interface; 
     char* address_listen = inet_ntoa(in); 
     //const char* address_listen = "0.0.0.0"; 
     std::string address_mcast = multicastAddress; 
     unsigned short address_port = port_num; 

     boost::system::error_code ec; 

     boost::asio::ip::address listen_addr = boost::asio::ip::address::from_string(address_listen, ec); 
     boost::asio::ip::address mcast_addr = boost::asio::ip::address::from_string(address_mcast, ec); 


     if (strcmp(network_type, "ipv4") == 0) 
     { 
      listen_endpoint_ = udp::endpoint(listen_addr, port_num); 
      send_endpoint_ = udp::endpoint(mcast_addr, port_num); 
     } 
     else if (strcmp(network_type, "ipv6") == 0) 
     { 
     } 
     else 
      return ES35_INVALID_SOCKET_CONNECTION; 

     send_udp_socket_.reset(new boost::asio::ip::udp::socket(send_ios_)); 
     receive_udp_socket_.reset(new boost::asio::ip::udp::socket(receive_ios_)); 

     send_udp_socket_->open(boost::asio::ip::udp::v4()); 
     receive_udp_socket_->open(listen_endpoint_.protocol()); 
     send_udp_socket_->set_option(boost::asio::ip::udp::socket::reuse_address(true)); 
     receive_udp_socket_->set_option(boost::asio::ip::udp::socket::reuse_address(true)); 

     boost::asio::ip::address_v4 local_interface = 
      boost::asio::ip::address_v4::from_string(address_listen); 
     boost::asio::ip::multicast::outbound_interface option(local_interface); 


     // Join the multicast group. 
     receive_udp_socket_->set_option(
      boost::asio::ip::multicast::join_group(mcast_addr)); 

     send_udp_socket_->set_option(option); 
     receive_udp_socket_->set_option(option); 

     boost::asio::ip::multicast::hops hops_option(3); 
     //send_udp_socket_->set_option(hops_option); 
     receive_udp_socket_->set_option(hops_option); 

     receive_udp_socket_->bind(listen_endpoint_); 


     startReceive(); 
     receive_thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &receive_ios_)); 
     send_thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &send_ios_)); 


     return ES_NoError; 
    } 
    catch (std::exception& exp) 
    { 
     std::string str = exp.what(); 
     return ES35_INVALID_SOCKET_CONNECTION; 
    } 
} 

/***************************************************************************//** 
\brief   
\details   
*******************************************************************************/ 
ARLErrorCode_e UDPClient::close(void) 
{ 
    try { 
     boost::system::error_code ec; 
     //udp_socket_->cancel(); 
     //udp_socket_.shutdown(socket_base::shutdown_both, ec); 
     if (ec) 
     { 
      return ES35_INVALID_SOCKET_CONNECTION; 
     } 
     if (send_udp_socket_->is_open()) 
     { 
      send_udp_socket_->close(); 
     } 
     if (receive_udp_socket_->is_open()) 
     { 
      receive_udp_socket_->close(); 
     } 

     receive_udp_socket_.reset(); 
     send_udp_socket_.reset(); 

    } 
    catch (std::exception& e) 
    { 
     std::string str = e.what(); 
     return ES35_INVALID_SOCKET_CONNECTION; 
    } 

    return ES_NoError; 
} 

/***************************************************************************//** 
\brief   
\details   
*******************************************************************************/ 
bool UDPClient::isOpen() 
{ 
    return send_udp_socket_->is_open() && receive_udp_socket_->is_open(); 
} 

/***************************************************************************//** 
\brief  Send a message.  
\details The message is sent asynchronously. 
\param  message 
\param  message size 
*******************************************************************************/ 
ARLErrorCode_e UDPClient::send(u8* message, u32 size) 
{ 
    if (!isOpen()) { 
     return ES35_INVALID_SOCKET_CONNECTION; 
    } 

    std::string send_to_address = send_endpoint_.address().to_string(); 



    send_udp_socket_->set_option(asio::ip::multicast::enable_loopback(false)); 

    send_udp_socket_->async_send_to(
     buffer(message, size), 
     send_endpoint_, 
     bind(
      &UDPClient::handleSend, 
      this, 
      asio::placeholders::error, 
      asio::placeholders::bytes_transferred)); 


    return ES_NoError; 
} 

/***************************************************************************//** 
\brief  Do nothing.   
\details This function has the required signature to be used as an 
      asynchronous send completion handler. 
\param  not used 
\param  not used 
*******************************************************************************/ 
void UDPClient::handleSend(const system::error_code& error, size_t) 
{ 
    if (error) 
    { 
     BoostSocketClient::onError(ES35_UDP_SEND_ERROR, (u8*)error.message().c_str(), error.message().size()); 
    } 
    else 
    { 
     send_udp_socket_->set_option(asio::ip::multicast::enable_loopback(true)); 
    } 
} 
/***************************************************************************//** 
\brief Start an asynchronous receiver.   
*******************************************************************************/ 
void NetLib::UDPClient::startReceive() 
{ 

    receive_udp_socket_->async_receive_from(
     buffer(_buffer), 
     sender_endpoint_, 
     bind(
      &UDPClient::handleReceive, 
      this, 
      asio::placeholders::error, 
      asio::placeholders::bytes_transferred)); 

    std::string sender_address = sender_endpoint_.address().to_string(); 
} 

/***************************************************************************//** 
\brief  Pass received data to the base class. 
\details A new receiver is started. 
\param  error code 
\param  data size 
*******************************************************************************/ 
void NetLib::UDPClient::handleReceive(const system::error_code& error, size_t size) 
{ 
    if (!error || error == error::message_size) 
    { 
     BoostSocketClient::onReceived(_buffer.data(), size); 

     startReceive(); 
    } 
    else   
    { 
     BoostSocketClient::onError(ES35_UDP_RECEIVE_ERROR, (u8*)error.message().c_str(), error.message().size()); 
    } 
} 


This code is not receiving response.please check 
+1

यदि आप एक संक्षिप्त स्पष्टीकरण के साथ-साथ कोड भी शामिल करते हैं तो यह बहुत बेहतर जवाब होगा। इस तरह यह न केवल समस्या हल करता है बल्कि यह भी दिखाता है कि इसे कैसे करें और क्यों। इस तरह हम सभी सीखते हैं। – Simon

संबंधित मुद्दे