本文介绍了在 unix 上提升 UDP 套接字问题 - 绑定:地址已在使用中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我知道同一主题还有其他几个主题,但我无法在其中找到任何可以帮助我的内容,因此我将尝试非常具体地说明我的情况.

First of all, I know there are several other threads on the same theme, but I was unable to find anything in those that could help me so I'll try to be very specific with my situation.

我设置了一个简单的 UDP 客户端/UDP 服务器对,负责在多个并行模拟之间发送数据.也就是说,模拟器的每个实例都在单独的线程中运行,并在 UDP 套接字上发送数据.在主线程中,服务器正在运行并在模拟之间路由消息.

I have set up a simple UDP Client / UDP Server pair that is responsible to send data between several parallel simulations. That is, every instance of the simulator is running in a separate thread and send data on a UDP socket. In the master thread the server is running and routes the messages between the simulations.

(对于这个问题)服务器代码的重要部分如下所示:

The (for this problem) important parts of the server code looks like this:

UDPServer::UDPServer(boost::asio::io_service &m_io_service) :
   m_socket(m_io_service, udp::endpoint(udp::v4(), PORT_NUMBER)),
   m_endpoint(boost::asio::ip::address::from_string("127.0.0.1"), PORT_NUMBER)
{
   this->start_receive();
};

void UDPServer::start_receive() {

   // Set SO_REUSABLE to true
   boost::asio::socket_base::reuse_address option(true);
   this->m_socket.set_option(option);

   // Specify what happens when a message is received (it should call the handle_receive function)
   this->m_socket.async_receive_from(   boost::asio::buffer(this->recv_buffer),
                                        this->m_endpoint,
                                        boost::bind(&UDPServer::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

};

这在我的 Windows 工作站上运行良好.

This works fine on my windows workstation.

问题是;我希望能够在 linux 集群上运行它,这就是我编译它并尝试在集群节点上运行它的原因.代码编译顺利,但当我尝试运行它时出现错误

The thing is; I want to be able to run this on a linux cluster, which is why I compiled it and tried to run it on a cluster node. The code compiled without a hitch, but when I try to run it I get the error

bind: address already in use

我使用 1024 以上的端口号,并且已验证它没有被其他程序使用.而且如上所示,我还设置了 reuse_address 选项,所以我真的不知道还有什么问题.

I use a port number above 1024, and have verified that it is not in use by another program. And as is seen above, I also set the reuse_address option, so I really don't know what else could be wrong.

推荐答案

便携使用 SO_REUSEADDR 你需要在将套接字绑定到通配符地址之前设置选项:

To portably use SO_REUSEADDR you need to set the option before binding the socket to the wildcard address:

UDPServer::UDPServer(boost::asio::io_service &m_io_service) :
   m_socket(m_io_service, udp::v4()),
   m_endpoint()
{
   boost::asio::socket_base::reuse_address option(true);
   this->m_socket.set_option(option);
   this->m_socket.bind(udp::endpoint(udp::v4(), PORT_NUMBER));
   this->start_receive();
}

在您的原始代码中,采用 endpoint 的构造函数在一行中构造、打开和绑定套接字 - 它简洁但不是很灵活.这里我们在构造函数调用中构造和打开套接字,然后在我们设置选项后绑定它.

In your original code, the constructor that takes an endpoint constructs, opens and binds the socket in a single line - it's concise but not very flexible. Here we're constructing and opening the socket in the constructor call, and then binding it later after we set the option.

顺便说一句,如果您只是想将它用作 async_receive_from 的 out 参数,那么初始化 m_endpoint 并没有多大意义.

As an aside, there's not much point initialising m_endpoint if you're just going to use it as the out argument of async_receive_from anyway.

这篇关于在 unix 上提升 UDP 套接字问题 - 绑定:地址已在使用中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 21:42