【问题标题】:C++ udp boost client doesn't receive udp messagesC ++ udp boost客户端不接收udp消息
【发布时间】:2020-12-18 14:24:20
【问题描述】:

当我跑步时:

nc -ul <ip address> <port>

我收到来自 udp 服务器的消息。但是,当我尝试使用下面的带有 boost 的 C++ 程序来重现等价物时,它只会在 receive_from 上冻结:

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

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

int main(int argc, char *argv[]) {
    try {
        if (argc != 3) {
            std::cerr << "Usage: client <host> <port>" << std::endl;
            return 1;
        }

        boost::asio::io_context ioContext;

        udp::resolver resolver(ioContext);
        udp::resolver::query query(udp::v4(), argv[1], argv[2]);
        udp::endpoint endpoint = *resolver.resolve(query);

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

//        boost::array<char, 1> sendBuf = {0};
//        socket.send_to(boost::asio::buffer(sendBuf), endpoint);

        char letter = 0;
        udp::endpoint sender_endpoint;
        while(socket.receive_from(boost::asio::buffer(&letter, 1), endpoint)) {
            std::cout << letter;
        }
    }
    catch (std::exception &e) {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}

此外,我只是在此处看到的教程中根据 boost udp 客户端代码对上述代码进行建模:

//
// client.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

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

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

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 2)
    {
      std::cerr << "Usage: client <host>" << std::endl;
      return 1;
    }

    boost::asio::io_context io_context;

    udp::resolver resolver(io_context);
    udp::endpoint receiver_endpoint =
      *resolver.resolve(udp::v4(), argv[1], "daytime").begin();

    udp::socket socket(io_context);
    socket.open(udp::v4());

    boost::array<char, 1> send_buf  = {{ 0 }};
    socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint);

    boost::array<char, 128> recv_buf;
    udp::endpoint sender_endpoint;
    size_t len = socket.receive_from(
        boost::asio::buffer(recv_buf), sender_endpoint);

    std::cout.write(recv_buf.data(), len);
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}

我怀疑教程代码不适用于我的情况?不知道出了什么问题或有什么区别。制作标准 udp echo 客户端的正确方法是什么?

【问题讨论】:

    标签: c++ sockets boost udp client


    【解决方案1】:

    我测试了以下代码成功接收消息。代码中的udp::resolver 不是必需的,因为您不是发送任何消息,而是接收消息。

    在您的情况下打开套接字时,您应该指定 UDP 期望数据的端口号。这可以通过将第二个参数传递给udp::socket 来完成。但是,您帖子中的第二个示例不需要这样做,因为它正在重用其端点 - sender_endpoint

    receive_from() 使用它的第二个参数来存储发送者的端点。您不应传递对等端的端点,而应传递一个变量来保存消息的来源。

    int main(int argc, char* argv[]) {
        try {
            if (argc != 3) {
                std::cerr << "Usage: client <host> <port>" << std::endl;
                return 1;
            }
    
            boost::asio::io_context ioContext;
            udp::socket socket(ioContext, udp::endpoint(udp::v4(), 6078));  // designated port
            
            char letter = 0;
            udp::endpoint ep_sender;
            while (socket.receive_from(boost::asio::buffer(&letter, 1), ep_sender)) {
                std::cout << letter;
                //std::cout << ep_sender.address().to_string() << endl; // sender's address.
            }
    
            return 0;
        }
        catch (std::exception& e) {
            std::cerr << e.what() << std::endl;
        }
    }
    

    【讨论】: