【问题标题】:Sending and receiveing UDP on the same port在同一端口上发送和接收 UDP
【发布时间】:2018-11-01 07:57:43
【问题描述】:

我使用X-Plane,它将其输出的UDP数据发送到127.0.0.1:49000。当我的应用程序应该通过boost::asio 侦听同一端口以接收数据时,问题就出现了。

我在herehere 使用了boost 示例代码。

// at main function:
udp_server server(49000);

// class implementation:
class udp_server
{
public:
    udp_server(int port) :
        io_service(),
        socket_(io_service, udp::endpoint(udp::v4(), port)) // Exception occurs here
    {
        start_receive();
        udp_thread = std::thread([this](){io_service.run();});
    }

    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));
    }

    // ...

    std::thread udp_thread;

    boost::asio::io_service io_service;
    udp::socket socket_;
    udp::endpoint remote_endpoint_;
    boost::array<char, 5000> recv_buffer_;
};

当我运行代码时,我在套接字初始化时收到一个异常:

bind:试图以访问权限禁止的方式访问套接字

这是有道理的,因为X-Plane 正在此端口写入,而我从同一个端口读取。我们俩都占用同一个港口。有没有办法克服这个问题?如果不是,是否意味着电脑上的两个应用程序无法通过UDP传递消息?

【问题讨论】:

    标签: c++ sockets boost boost-asio


    【解决方案1】:

    这是有道理的,因为 X-Plane 在这个端口写入,而我从同一个端口读取。

    X-Plane 正在从该端口发送 并接收 该端口。它将数据报写入(并从其接收数据报)它必须与之通信的程序正在接收和发送的任何端口。

    我们俩都占用同一个端口。有什么办法可以解决这个问题吗?

    是的,选择一个不同的端口发送来自和接收on

    如果不是,是否意味着电脑上的两个应用程序无法通过UDP传输消息?

    他们当然可以。通常,一方会选择一个众所周知的端口,用于发送和接收。另一端使用一个随机端口发送和接收,发送到已知端口并从已知端口接收。

    所以流程是:

    1. X-Plane 始终绑定到已知端口 49,000。
    2. 您选择一个随机端口,例如 31,020。你绑定到那个端口。
    3. 您将数据报从端口 31,020 发送到端口 49,000,因为这是 X-Plane 的知名端口。
    4. X-Plane 接收从端口 31,020 到端口 49,000 的数据报,这是它绑定的端口。 X-Plane 注意到数据报来自端口 31,020。
    5. X-Plane 向端口 31,020 发送响应,该端口是您的程序从端口 49,000 监听的端口,它绑定到并从该端口发送。
    6. 您的程序从端口 49,000 到端口 31,020(它正在侦听的端口)接收数据报。
    7. 您的程序知道这是来自 X-Plane 的响应,因为它来自端口 49,000。

    【讨论】:

    • You pick a random port, say 31,020. You bind to that port,现在我明白了。您能否建议如何在上面的代码中绑定端口?我在谷歌上的搜索带来了boos::bind,这是无关紧要的。
    • @Danze 你可能不需要做任何事情。如果你不bind 到一个端口,实现将选择一个随机的“临时”端口。如果必须指定端口,请指定零。
    • 如果我设置port=0,那么我应该如何告诉boost::asio来源是:49000?它将如何找到源头?
    • 不需要找源头。您只需向 49,000 发送数据报,X-Plane 服务器就会向您的源端口发送回复,无论它是什么。您不需要知道来源即可接收数据报——如果您知道,X-Plane 将如何工作?它不知道谁将发送给它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 2023-04-02
    • 2022-11-19
    • 2012-02-25
    相关资源
    最近更新 更多