2009-07-26 102 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

相关问题