我有一个 TCP 服务器在无限循环中运行,如下面的伪代码:
while (true)
{
auto new_connected_socket = accept(listening_socket,...);
// Here it may block for a long time
std::thread(fn_new_connection_handler, new_connected_socket);
}
如果管理员想要停止TCP服务器,必须要很好地打破死循环。
我想到的一种方法是使用特殊的套接字连接到 TCP 服务器。套接字之所以“特殊”,是因为它的源IP是“特殊”的,例如255.255.255.255显然不是合法的源IP。
如果合法,那么客户端的伪代码可能如下所示:
auto special_socket = socket(...);
bind(special_socket, "255.255.255.255", ...);
connect(special_socket, tcp_server_addr, ...);
服务器端伪代码如下:
while (true)
{
auto new_connected_socket = accept(listening_socket,...);
// Here it may block for a long time
if (IsSpecialSourceIp(new_connected_socket))
{
break; // Exit the server thread.
}
else
{
std::thread(fn_new_connection_handler, new_connected_socket);
}
}
这个解决方案可行吗?
最佳答案
如 manpage of accept 中所述(man 2 accept
) 您可以将套接字标记为非阻塞操作并使用 select或 poll找出连接是否正在等待。或者甚至重复调用 accept 并检查 EAGAIN 或 EWOULDBLOCK 作为返回值,中间有足够的停顿。
当然,select 或 poll 是更好的选择,因为您不需要“忙等待”,并且您会得到新连接的即时通知(延迟更低)。与阻止代码并执行一些晦涩的套接字魔术来关闭服务器相比,这无疑是一个更好的解决方案。
关于c++ - 我可以将任意源 IP 绑定(bind)到套接字吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14534731/