0

我正在尝试为 UDP 通信创建一个 s-function(使用 C++ Boost 库)。

实现发件人非常简单,只需 15 分钟。我正在努力让接收器工作。

我在 Visual Studio 中创建了以下内容:

#define _WIN32_WINNT 0x0501
#define BOOST_ASIO_ENABLE_HANDLER_TRACKING 

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

typedef unsigned char   UINT8;
typedef unsigned short  UINT16;

using boost::asio::ip::udp;
using namespace std;

std::vector<char>       receive_buffer;

void process_received_frame(const boost::system::error_code& error, size_t received_frame_size) {
    if (error) {
        cout << "Receive failed: " << error.message() << "\n";        
        return;
    }

    size_t ByteCount = 0;

    std::cout << endl << "Received byte stream (Handler) [" << received_frame_size << "]: ";
    for (std::vector<char>::const_iterator iter = receive_buffer.cbegin(); iter != receive_buffer.cend(); iter++)
    {
        ByteCount++;

        printf("%02X ", (UINT8)*iter);

        if (ByteCount == received_frame_size)
        {
            break;
        }
    }
    std::cout << endl;
}

int main(int argc, char *argv[])
{
    boost::asio::io_service io_service;
    udp::socket             socket(io_service);   
    udp::endpoint           remote_endpoint = udp::endpoint(boost::asio::ip::address_v4::from_string("127.0.0.1"), 19001);

    socket.open(udp::v4());
    socket.bind(udp::endpoint(remote_endpoint));   

    receive_buffer.resize(255);

    try
    {
        socket.async_receive_from(boost::asio::buffer(receive_buffer),
            remote_endpoint,
            boost::bind(&process_received_frame, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
    }
    catch (const std::exception& exp)
    {
        printf("%s\n", exp.what());
    }

    //io_service.poll();
    io_service.run();

    cout << "End";

    std::cin.ignore();
}

我尝试从 Simulink 将 UDP 发送到 localhost:19001 并且能够在 Visual Studio 中接收 UDP 数据包。处理程序(process_received_frame)被调用,一切似乎都按预期工作。

但是,鉴于 io_service::run() 在阻塞模式下工作,如果端口 19001 上没有收到任何内容,它会暂停执行。所以我尝试使用 io_service::poll() (在上面的代码中注释)。但是,当我使用 poll() 时,它不会执行处理程序。如果我尝试从 main() 显示“receive_buffer”的内容,我会得到全 0。有趣的是,当我单步执行访问“receive_buffer”元素的代码时,我确实得到了正确的值。

不知道我做错了什么。很可能是小学生的错误。

当我将它转换为 MATLAB-Simulink 的 s 函数时,它会做同样的事情——全为零。

任何帮助将非常感激。

干杯,

4

1 回答 1

0

在您的处理程序函数中,您需要socket.async_receive_from在处理完答案后最后调用。io_service.run()当处理队列中没有更多处理程序时返回。

在此处查看来自 boost doc 的示例:udp 同步服务器示例

编辑

重读您的问题/评论,我不确定您的预期输出或行为是什么。

如果您只期待一个 UDP 帧,那么也许调用io_service.run_one().

如果您不想run()阻塞主线程,则需要启动另一个线程来调用run(). 就像是:

boost::asio::io_service io_service;
// Process handlers in a background thread.
boost::thread t(boost::bind(&io_service::run, &io_service));  
...

io_service::run()始终是阻塞调用。完成处理程序只能从当前调用的线程中调用run()。唯一run()会返回的时间是队列中没有更多处理程序(您停止调用async_receive)或者您通过调用或显式取消run()命令时stop()reset()

于 2017-07-18T13:51:34.777 回答