为什么Boost Boost不能多次接收UDP数据包?

时间:2019-10-29 21:42:14

标签: boost boost-asio

提示:如果我在io_context循环中实例化for,则可以使用此功能。

我知道这段代码看起来有些愚蠢,但这是简化的代码版本,它更大并且具有这种结构。为什么我不能再收到包含以下代码的数据包? bool synch = true;可以正常工作。这是我得到的输出:

iteration 0
receive udp
posted receive
got a packet
iteration 1
receive udp
posted receive

我必须按Ctrl-c退出。我希望第二次看到“丢包”。

接收方:

#include <array>
#include <iostream>
#include <functional>
#include <thread>

#include <boost/asio.hpp>

namespace asio = boost::asio;
namespace ip = asio::ip;

using ip::udp;
using std::cout;
using std::endl;

using boost_ec = boost::system::error_code;

int main() {
    asio::io_context ioContext;

    std::array<char, 65500> buffer;
    auto asioBuffer = asio::buffer(buffer);

    bool synch = false;

    udp::endpoint remoteEndpoint;

    for (unsigned int i = 0; i < 2; ++i) {
        cout << "iteration " << i << endl;

        auto recvSocket = udp::socket(ioContext,
                                      udp::endpoint(udp::v4(), 9090));

        if (synch) {
            recvSocket.receive_from(asioBuffer, remoteEndpoint);
            cout << "received a packet" << endl;
        } else {
            std::function<void(const boost_ec&, size_t)> impl =
                [&](const boost_ec &, size_t packetSize) {

                    if (packetSize > 0) {
                        cout << "got a packet" << endl;
                        return;
                    }

                    cout << "receive udp" << endl;

                    recvSocket.async_receive_from(asioBuffer,
                                                  remoteEndpoint,
                                                  impl);
                    cout << "posted receive" << endl;
                };

            impl(boost_ec(), 0);

            while (ioContext.poll() == 0) {
                std::this_thread::sleep_for(std::chrono::milliseconds(200));
            }
        }
    }
}

发件人:

#include <array>
#include <iostream>

#include <boost/asio.hpp>

namespace asio = boost::asio;
namespace ip = asio::ip;
namespace chrono = std::chrono;

using ip::udp;
using std::cout;
using std::endl;

int main() {
    std::array<char, 65500> buffer;
    asio::io_context ioContext;

    auto socket = udp::socket(ioContext);
    socket.open(udp::v4());

    auto endpoint = udp::endpoint(udp::v4(), 9090);

    size_t packetsSent = 0;
    size_t bytesSent = 0;

    const double APPROX_BYTES_PER_SEC = 1e6;
    const auto CHECK_INTERVAL = chrono::microseconds(100);

    auto beforeStart = chrono::steady_clock::now();
    auto start = beforeStart;
    size_t bytesSentSinceStart = 0;

    while (true) {
        auto now = chrono::steady_clock::now();
        auto timePassed = now - start;
        if (timePassed > CHECK_INTERVAL) {
            auto expectedTime = chrono::duration<double>(bytesSentSinceStart /
                                                         APPROX_BYTES_PER_SEC);
            if (expectedTime > timePassed) {
                std::this_thread::sleep_for(expectedTime - timePassed);
            }
            start = chrono::steady_clock::now();
            bytesSentSinceStart = 0;
        }

        bytesSent += socket.send_to(asio::buffer(buffer), endpoint);
        bytesSentSinceStart += buffer.size();
        ++packetsSent;
    }

    return 0;
}

1 个答案:

答案 0 :(得分:0)

我认为this是关键:

void restart();

  

当由于io_context停止或返回而导致对这些函数的先前调用返回时,必须在对run(),run_one(),poll()或poll_one()函数进行任何第二次或更多次调用之前调用此函数。没有工作。

因此,上述代码需要在导致restart为真的每个poll之后调用ioContext.stopped(),并且当ioContext不再附加任何内容来等待发生时,它变为true