我有一个程序在 TCP 端口上侦听特定字符串并使用execlp
调用启动应用程序。我正在做一个在这个调用fork()
之前启动一个子进程。execlp
在此启动后,父进程再次开始在同一端口上侦听。我正在关闭子进程中的套接字。
在绑定套接字之前,我已经编写了一个包装器来boost::asio::tcp_socket
设置addr_reuse
选项。true
现在我的问题是在 Linux 中,我在应用程序启动几次后收到地址重用错误。在我的程序中,它不断尝试接受连接(或更准确地说,尝试安排接受到boost::asio::io_service
)直到绑定然后接受成功。所以我在这个循环中收到错误。
奇怪的是,如果我关闭(或杀死)已启动的可执行文件,此错误将停止出现,这意味着bind
成功。我确信在启动的应用程序中没有在任何地方使用相同的端口。我正在使用异步套接字操作。知道为什么我会收到此错误吗?
这是我在套接字上接受的方式:(boost::asio::tcp_socket(_tcpSocket)
在开始新的接受之前,我还在共享指针上调用了重置。)
boost::asio::ip::tcp::endpoint endPoint(boost::asio::ip::tcp::v4(), port);
_acceptor.reset ( new boost::asio::ip::tcp::acceptor( *_ioService.get() ) );
_acceptor->open( endPoint.protocol() );
_acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
boost::system::error_code ec;
_acceptor->bind(endPoint, ec);
if ( ec.value() != boost::system::errc::success )
{
ec.clear();
_acceptor->close(ec);
close();
return false;
}
ec.clear();
_acceptor->listen(boost::asio::socket_base::max_connections, ec);
if ( ec.value() != boost::system::errc::success )
{
return false;
}
_acceptor->async_accept(*_tcpSocket,
boost::bind(&TCPSocket::_handleAsyncAccept,
this,
boost::asio::placeholders::error) );
这是我的分叉方式:
pid_t pid = fork();
switch (pid)
{
case 0:
{
/// close all sockets for child process. as it might cause addr reuse error in parent process
_asyncNO->closeAll();
std::string binary = "<binaryName>";
std::string path = "<binaryPath>";
if ( execlp( path.c_str(), binary.c_str(), controllerIP.c_str(), (char *)0 ) == -1 )
{
LOG_ERROR("System call failed !!")
}
}
break;
default:
}
为简单起见,我删除了日志记录。