简体   繁体   English

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

[英]Boost::Asio Async UDP Server - Unhandled Exception Message

I am fairly new to C++ programming, coming from a background in embedded C. I am trying to put together a project with a UDP receiver using Boost::Asio and when debugging the code I receive an 'Unhandled exception' dialog in MS Visual Studio Express 2012. 我是C ++编程的新手,来自嵌入式C的背景。我试图使用Boost :: Asio将项目与UDP接收器放在一起,并在调试代码时在MS Visual Studio中收到“未处理的异常”对话框Express 2012。

Is this really an error or simply run-time feedback because I do not have exception handling code? 这是真的错误还是因为没有异常处理代码而只是运行时反馈?

I have a singleton class called UDP_Listener that initiates an async_receive_from on a socket member variable. 我有一个名为UDP_Listener的单例类,该类在套接字成员变量上启动async_receive_from。 In my main thread of execution, I spawn another thread to execute io_service::run() and create the instance of UDP_Listener. 在执行的主线程中,我产生了另一个线程来执行io_service :: run()并创建UDP_Listener的实例。

This is the code from the main thread of execution that creates the network object: 这是创建网络对象的主要执行线程中的代码:

// 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;
}

The UDP_Listener class has the header file: 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;
};

and the implementation(simplified here to remove irrelevant functions): 和实现(此处简化为删除不相关的功能):

#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();
    }
}

When compiling and executing with the VS debugger, I get this message: boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> > at memory location 0x0674F180. 使用VS调试器进行编译和执行时,出现以下消息: boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> > at memory location 0x0674F180.

I am afraid I am doing something fundamentally wrong here, considering I am inexperienced with networking, thread management and C++ with an OS. 考虑到我对网络,线程管理和OS的C ++经验不足,因此我在这里所做的根本上是错误的。 I do not want to proceed in my application with intrinsically flawed coding! 我不想在应用程序中进行本质上有缺陷的编码!

First thing I see is that you are calling the ioservice run on a separate thread before you give it asynchronous work to do. 我首先看到的是,您要在单独的线程上运行ioservice,然后再让它执行异步工作。 This will cause that run method to immediately exit out and your asynchronous call will never fire because the io service is not running. 这将导致该run方法立即退出,并且由于io服务未运行,您的异步调用将永远不会触发。 Also I would call the ioservice run with an error code so you can catch any errors like this: 另外,我会用错误代码调用ioservice运行,以便您可以捕获这样的任何错误:

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

Another place where errors are likely to occur is when a socket is bound. 绑定套接字可能会导致错误发生。 You are binding the socket using its constructor to port 12345 but what happens if that port already has a socket bound to it? 您正在使用套接字的构造函数将套接字绑定到端口12345,但是如果该端口已经绑定了套接字会发生什么呢? what if you dont have permission to bind to a port? 如果您没有绑定端口的权限怎么办? It is good practice to pass error codes and handle them. 传递错误代码并进行处理是一种很好的做法。 Here is an example: 这是一个例子:

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 

The exception you are getting is the result of not handling one of these boost error codes. 您得到的异常是未处理这些增强错误代码之一的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM