首先,我知道在同一主题上还有其他几个主题,但是我无法find那些能够帮助我的东西,所以我会试着对我的情况非常具体。
我已经build立了一个简单的UDP客户端/ UDP服务器对,负责在几个并行模拟之间发送数据。 也就是说,模拟器的每个实例都在一个单独的线程中运行,并在UDP套接字上发送数据。 在主线程中,服务器正在运行,并在模拟之间路由消息。
(对于这个问题)服务器代码的重要部分如下所示:
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工作站上正常工作。
事情是; 我希望能够在linux集群上运行它,这就是为什么我编译它并试图在集群节点上运行它的原因。 代码编译没有一丝困难,但是当我尝试运行它时,我得到的错误
bind: address already in use
我使用1024以上的端口号,并validation了它没有被另一个程序使用。 正如上面所看到的,我也设置了reuse_address
选项,所以我真的不知道还有什么可能是错的。
要可移植地使用SO_REUSEADDR
,需要在将套接字绑定到通配符地址之前设置该选项:
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
构造,在一行中打开和绑定套接字 – 它很简洁,但不是很灵活。 这里我们构造并在构造函数调用中打开套接字,然后在设置选项后再绑定它。
m_endpoint
如果你只是将它用作async_receive_from
的out参数,那么没有太多的意思是初始化m_endpoint
。
尝试在Linux上运行以下命令,查看该端口是否已被另一个程序使用。
netstat -antup | grep 1024
如果你正在使用“已经在使用的地址”,那么肯定会被其他程序使用。 如果上面的命令产生了一些结果,那么杀死命令中报告的进程ID。 如果这不起作用,请尝试将端口号更改为其他任意端口,并检查问题是否仍然存在。