2009-07-26 82 views
0

下面的類的boost :: ASIO不起作用

頭:

namespace msgSrv { 

class endPoint { 

public: 
    asio::ip::udp::endpoint ep; 
    endPoint(std::string ip, int port); 

}; 

class msgSrv { 

private: 
    asio::ip::udp::socket *asioSocket; 
    asio::io_service *asioIoService; 
    int listenPort; 
    boost::array<char, 1> rcvBuff; 
    asio::ip::udp::endpoint lastRcvdPcktEndp; 
    char * sbuff; 

public: 

    boost::condition_variable cond; 
    boost::mutex mut; 
    msgSrv(int listenPort); 
    virtual ~msgSrv(); 

    void start(); 
    void pckRcvd(const asio::error_code& error, std::size_t bytes_transferred); 
    void sendTo(const char* buff, int len, endPoint ep); 
    void sendHnd(const asio::error_code& error, std::size_t bytes_transferred); 

}; 

} 

在.cpp

#include "msgSrv.h" 

namespace msgSrv { 

endPoint::endPoint(const std::string ip, int port) { 
    asio::ip::address addr = asio::ip::address::from_string(ip); 
    ep = asio::ip::udp::endpoint(addr, port); 
} 

msgSrv::msgSrv(int listenPort) { 
    // TODO Auto-generated constructor stub 
    this->listenPort = listenPort; 
    try { 
     asioIoService = new asio::io_service(); 
     asioSocket = new asio::ip::udp::socket(*asioIoService, 
       asio::ip::udp::endpoint(asio::ip::udp::v4(), listenPort)); //new asio::ip::udp::socket_(*asioIoService, udp::endpoint(udp::v4(), listenPort)); 
    } catch (std::exception &e) { 
     std::cerr << "Error initializing ioservice or socket:" << e.what(); 
    } 
    asioIoService->run(); 

} 

msgSrv::~msgSrv() { 
    // TODO Auto-generated destructor stub 
    delete asioIoService; 
    delete asioSocket; 
} 

void msgSrv::start() { 

    asioSocket->async_receive_from(asio::buffer(rcvBuff), lastRcvdPcktEndp, 
      boost::bind(&msgSrv::pckRcvd, this, asio::placeholders::error, 
        asio::placeholders::bytes_transferred)); 

} 

void msgSrv::pckRcvd(const asio::error_code& error, 
     std::size_t bytes_transferred) { 
    std::cout << "Rcvd! " << lastRcvdPcktEndp.address().to_string() << ":" 
      << lastRcvdPcktEndp.port() << "\n"; 
} 

void msgSrv::sendTo(const char* buff, int len, endPoint ep) { 
    sbuff = new char[len]; 
    mempcpy(sbuff, buff, len); 
    asioSocket->async_send_to(asio::buffer(sbuff, len), ep.ep, boost::bind(
      &msgSrv::sendHnd, this, asio::placeholders::error, 
      asio::placeholders::bytes_transferred)); 

} 

void msgSrv::sendHnd(const asio::error_code& error, 
     std::size_t bytes_transferred) { 
    std::cout << "Snt!\n"; 

    delete sbuff; 
} 

} 

和下面的 「主要」 文件:

int main() 
{ 
    msgSrv::msgSrv aa(4450); 
    aa.start(); 
    msgSrv::endPoint ep("127.0.0.1", 4450); 
    std::string a("Prova!"); 
    int len = a.length(); 
    aa.sendTo(a.c_str(), len, ep); 
    std::cout << "sent...\n"; 
    std::cout << "notified...\n"; 
} 

我所得到的全部是:

terminate called after throwing an instance of 'asio::system_error' 
    what(): mutex: Invalid argument 
sent... 
notified... 

怎麼回事?我甚至試圖在主體中放置一段時間(1),以查看是否發生了什麼......我甚至試圖在接收處理程序解鎖的主體中放置一個條件......所有都保持鎖定......所以???不知道!

回答

1

我沒有看到你實際上鎖定了任何muxtex,所以這個錯誤很奇怪。

但是你的問題是在構造函數裏調用asioIoService->run(),女巫陷入無限循環。解決方案是創建一個新的boost::thread,女巫自己撥打asioIoService->run()。此線程將處理所有作業。您也可以使用多個線程調用asio :: io_service :: run(),以便同時處理多個作業。

m_thread = new boost::thread(boost::bind(&asio::io_service::run,asioIoService)); 

調用asioIoService->stop()將迫使ASIO :: io_service對象的退出:: run()中,從而關閉線程。您必須加入此線程才能確保線程在銷燬msgSrv類的析構函數中的指針之前終止。

+3

我的七年級語言藝術老師用尖刺的棍子打敗了我們,直到我們得到了正確的答案......女巫戴着一頂黑帽子......這是一個可供選擇的選擇。總是把它拼成你的90%的時間。 – 2009-11-04 17:43:31