【问题标题】:boost udp receiver on linux failslinux上的boost udp接收器失败
【发布时间】:2014-01-24 09:32:15
【问题描述】:

我正在从 windows 向 linux 发送 udp 单播数据包。

我使用 boost 编写了简单的应用程序 udp 客户端和服务器。

我在 windows 上运行客户端(udp 发送方),在 linux 上运行服务器(udp 接收方)。

我的客户端正在发送 udp 数据包,但我在 linux 上的 udp 接收器没有收到数据包。但我可以在wireshark(在我的linux pc上运行)上看到udp数据包。

我测试了端口和ipaddress,一切正常。

下面是在linux上运行的代码。

如果我在 windows 上同时运行(客户端和服务器),它工作正常

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

class udp_server
{
public:
  udp_server(boost::asio::io_service& io_service)
    : socket_(io_service, udp::endpoint(udp::v4(), 7799))
  {
    start_receive();
  }

private:
  void start_receive()
  {
    socket_.async_receive_from(
        boost::asio::buffer(recv_buffer_), remote_endpoint_,
        boost::bind(&udp_server::handle_receive, this,
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
  }

  void handle_receive(const boost::system::error_code& error,
      std::size_t /*bytes_transferred*/)
  {
    if (!error || error == boost::asio::error::message_size)
    {

      start_receive();
    }
  }

  udp::socket socket_;
  udp::endpoint remote_endpoint_;
  boost::array<char, 1> recv_buffer_;
};

int main()
{
  try
  {
    boost::asio::io_service io_service;
    udp_server server(io_service);
    io_service.run();
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

return 0;
}

【问题讨论】:

  • 我无法帮助您编写代码,但您是否完全从 boost.org 复制了代码示例?如果不是从那开始

标签: boost boost-asio


【解决方案1】:

UDP 是一种数据报协议。该协议是无状态的,数据包需要作为单个数据包接收。

有关背景信息,请参阅Beej's Guide to Networking

但是,您的接收缓冲区是 1 个字节。您不能期望读取超过第一个字节。

这看起来可能是从例如复制tutorial 6 listing。不同之处在于,这是一项不关心请求的日间服务。它想知道的只是“收到了一个数据包”,它只会无条件地发送白天的响应。

因此,解决方案似乎是增加缓冲区大小。如果包的大小无法预测/没有限制,请考虑切换到流套接字(TCP/IP)。

这里,作为奖励,使用 c++11 风格:

#include <boost/asio.hpp>

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

class udp_server
{
    public:
        udp_server(boost::asio::io_service& io_service)
            : socket_(io_service, udp::endpoint(udp::v4(), 7799))
        {
            start_receive();
        }

    private:
        void start_receive()
        {
            socket_.async_receive_from(
                boost::asio::buffer(recv_buffer_), remote_endpoint_,
                [this](boost::system::error_code ec, std::size_t bytes_transferred)
                {
                    if (!ec && (bytes_transferred > 0))
                    {
                        std::cout << "PACKET[" << std::string(&recv_buffer_[0], &recv_buffer_[0]+bytes_transferred) << "]\n";
                    } else
                        throw ec; // TODO
                    start_receive();
                });
        }

        udp::socket socket_;
        char recv_buffer_[1024];
        udp::endpoint remote_endpoint_;
};

int main()
{
    std::cout << std::unitbuf;
    try
    {
        boost::asio::io_service io_service;
        udp_server server(io_service);
        io_service.run();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
}

【讨论】:

  • 嗨,谢谢这工作正常.. 现在我面临其他问题,我正在加入一些多播 IP 并发送一些数据包。现在我需要获取发送方端口,我从 192.168.1.111:P1 发送到 239.255.255.250:1900 .. 这里 P1 是由 boost 随机选择的,我需要获取该端口并传递给这个接收器开始监听上
  • 不读你的代码:你试过socket.bind()boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-18
相关资源
最近更新 更多