即使没有传入消息,也会增强ASIO UDP客户端async_receive_from调用处理程序

时间:2014-11-08 17:54:06

标签: c++ boost udp boost-asio

我已将Boost日间客户端教程中的UDP客户端代码修改为以下内容:

class UDPClient
{
public:
    udp::socket* socket;
    udp::endpoint* receiver_endpoint;
    boost::array<char, 1024> recv_buffer;

    UDPClient();
    void do_receive();
    void handle_receive(const boost::system::error_code& error, size_t);
};

UDPClient::UDPClient()
{
    boost::asio::io_service io_service;

    udp::resolver resolver(io_service);
    udp::resolver::query query(udp::v4(), "127.0.0.1", "8888");
    receiver_endpoint = new udp::endpoint(*resolver.resolve(query));

    socket = new udp::socket(io_service);
    socket->open(udp::v4());

    do_receive();

    while (true)
    {
        io_service.poll();
        Sleep(1);
    }
}

void UDPClient::do_receive()
{
    socket->async_receive_from(boost::asio::buffer(recv_buffer), *receiver_endpoint,
                               boost::bind(&UDPClient::handle_receive, this,
                               boost::asio::placeholders::error,
                               boost::asio::placeholders::bytes_transferred));
}

void UDPClient::handle_receive(const boost::system::error_code& error, size_t bytes_transferred)
{
    cout << "ulala" << endl;

    if (!error || error == boost::asio::error::message_size)
        do_receive();
}

如果一切按计划进行,&#34; ulala&#34;只有在收到消息时才会打印。然而,这不是这里的情况......处理程序被即时调用并且&#34; ulala&#34;无论是否有传入消息,都会打印。我尝试了一些不同的东西:使用io_service.run()和io_service.run_one()交换io_service.poll(),以及删除Sleep(1),但这些更改都不会对问题产生任何影响。我该怎么办?

提前致谢!

1 个答案:

答案 0 :(得分:3)

socket = new udp::socket(io_service);
socket->open(udp::v4());

设置一个套接字以发送到任意端点。要接收(&#34;听&#34;),请使用

socket = new udp::socket(io_service, udp::endpoint(udp::v4(), 8888));

除此之外,socket和receiver_endpoint现在泄露了。解决这个问题:

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>
#include <iostream>

using boost::asio::ip::udp;

class UDPClient
{
public:
    boost::asio::io_service io_service;
    udp::socket socket;
    udp::endpoint receiver_endpoint;
    boost::array<char, 1024> recv_buffer;

    UDPClient();
    void do_receive();
    void handle_receive(const boost::system::error_code& error, size_t);
};

UDPClient::UDPClient()
    : io_service(),
      socket(io_service, {udp::v4(), 8888})
{
    do_receive();
    io_service.run();
}

void UDPClient::do_receive()
{
    socket.async_receive_from(boost::asio::buffer(recv_buffer), receiver_endpoint,
                               boost::bind(&UDPClient::handle_receive, this,
                               boost::asio::placeholders::error,
                               boost::asio::placeholders::bytes_transferred));
}

void UDPClient::handle_receive(const boost::system::error_code& error, size_t bytes_transferred)
{
    std::cout << "ulala" << std::endl;
    std::cout << "Received: '" << std::string(recv_buffer.begin(), recv_buffer.begin()+bytes_transferred) << "'\n";

    if (!error || error == boost::asio::error::message_size)
        do_receive();
}

int main()
{
    UDPClient updclient;
}

这也会打印收到的消息(假设它是可打印的)。见

是一种可以同时处理多个UDP请求的方法。