Boost::Asio异步UDP服务器-未处理的异常消息



我对c++编程相当陌生,来自嵌入式C的背景。我试图使用Boost::Asio与UDP接收器组合一个项目,在调试代码时,我在MS Visual Studio Express 2012中收到一个"未处理的异常"对话框。

这真的是一个错误或简单的运行时反馈,因为我没有异常处理代码?

我有一个名为UDP_Listener的单例类,它在套接字成员变量上启动async_receive_from。在执行的主线程中,我生成另一个线程来执行io_service::run()并创建UDP_Listener的实例。

这是执行主线程中创建网络对象的代码:

// UDP listener initialisation
try{
    // io_service and the work object to keep it from returning immediately
    boost::asio::io_service io_service;
    boost::asio::io_service::work work(io_service);
    // Spawn a new thread to execute the io_service run() method
    boost::thread(boost::bind(&boost::asio::io_service::run, &io_service));
    // Create the UDP listener object - singleton class
    m_pListener = new UDP_Listener(io_service);
}
catch (std::exception& e)
{
    std::cerr << e.what() << std::endl;
}

UDP_Listener类有头文件:

#pragma once
#include "boost_1_58_0/boost/array.hpp"
#include "boost_1_58_0/boost/asio.hpp"
#include "boost_1_58_0/boost/bind.hpp"
#include "Target.h"
class UDP_Listener
{
public:
    // Constructor
    UDP_Listener(boost::asio::io_service& io_service);
    // Destructor
    ~UDP_Listener(void);
    // Start an async receive from the member socket
    void asyncReceive(void);
    // Create a list of target objects from the received byte array
    void buildTargetList(void);
private:
    void handleReceive(const boost::system::error_code& error, 
        std::size_t /*bytes_transferred*/);
    void handleSend(boost::shared_ptr<std::string> /*message*/,
      const boost::system::error_code& /*error*/,
      std::size_t /*bytes_transferred*/);
    boost::asio::ip::udp::socket m_socket;
    boost::asio::ip::udp::endpoint m_remote_endpoint;
    // Received byte array
    boost::array<signed char, 8192> m_recv_buffer;
    boost::asio::io_service& m_io_service;
    // List of target objects most recently received
    std::vector<Target> m_target_list;
    // The distance resolution (16 metres / 2^7 bits representation)
    FLOAT d_step;// = 0.125f;
    // The speed resolution (15.3 km/h / 2^7 signed bits)
    FLOAT s_step;// = 0.24f;
};

和实现(这里简化以删除不相关的函数):

#include "UDP_Listener.h"
using boost::asio::ip::udp;
/// <summary>
/// Constructor
/// </summary>
UDP_Listener::UDP_Listener(boost::asio::io_service &io_service)
    : m_io_service(io_service),
      m_socket(io_service, udp::endpoint(udp::v4(), 12345))
{
    d_step = 0.125f;
    s_step = 0.24f;
    // Start listening for UDP packets
    asyncReceive();
}
/// <summary>
/// Destructor
/// </summary>
UDP_Listener::~UDP_Listener(void)
{
    //m_io_service.stop();
    m_socket.shutdown(boost::asio::ip::udp::socket::shutdown_both);
    m_socket.close();
}
/// <summary>
/// Start listening for UDP packets
/// </summary>
void UDP_Listener::asyncReceive()
{
    m_socket.async_receive_from(
        boost::asio::buffer(m_recv_buffer), m_remote_endpoint,
        boost::bind(&UDP_Listener::handleReceive, this,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
}
/// <summary>
/// Handler for received packets
/// </summary>
void UDP_Listener::handleReceive(const boost::system::error_code& error,
      std::size_t /*bytes_transferred*/)
{
    if (!error || error == boost::asio::error::message_size)
    {
        if (m_recv_buffer[0] == 0x19 && m_recv_buffer[1] == 0x73)
        {   
            m_target_list.clear();
            buildTargetList();
        }
        asyncReceive();
    }
}

当编译和执行与VS调试器,我得到这个消息:boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> > at memory location 0x0674F180.

我担心我在这里做了一些根本性的错误,考虑到我对网络,线程管理和操作系统的c++缺乏经验。我不想继续在我的应用程序与本质上有缺陷的编码!

我看到的第一件事是,在您给它异步工作之前,您正在单独的线程上调用ioservice运行。这将导致run方法立即退出,并且您的异步调用将永远不会触发,因为io服务没有运行。此外,我将调用带有错误代码的ioservice运行,以便您可以捕获任何错误,如下所示:

boost::system::error_code ec;
boost::thread(boost::bind(&boost::asio::io_service::run, &io_service, ec));
if (ec)
//do error checking here

另一个可能发生错误的地方是绑定套接字的时候。您正在使用套接字的构造函数将其绑定到端口12345,但如果该端口已经绑定了套接字,会发生什么?如果你没有绑定端口的权限怎么办?传递错误代码并处理它们是一种很好的做法。下面是一个例子:

boost::system::error_code ec;
boost::asio::ip::address_v4 address = boost::asio::ip::address_v4::any();
boost::asio::udp::endpoint ep(address, 12345)
boost::asio::udp::socket sock(io_service);
sock.open(boost::asio::ip::udp::v4(), ec);
if (ec)
    //do error checking here
sock.bind(ep, ec);
if (ec)
    //do error checking here
//now do any reads or writes 

您得到的异常是没有处理这些boost错误代码之一的结果。

相关内容

最新更新