调用listen(fd,backlog)后,是否可以在套接字上取消删除?
编辑:我没有弄清楚自己的错误。我希望能够暂时解除套接字的问题。调用close()会使套接字处于M2LS状态并阻止我重新打开它(或者更糟糕的是,某些恶意程序可以绑定到该套接字)
暂时取消隐藏将是向上游负载均衡器发出信号的一种方式(可能不是最佳方式)此应用暂时无法接受任何更多请求
答案 0 :(得分:5)
关闭套接字后,你的程序可能仍然告诉你套接字“正在使用”,这是因为我不确切知道一些奇怪的问题。但是有关套接字的联机帮助页显示,有一个标志可以重用同一个套接字,懒得称之为:“SO_REUSEADDR”。使用“setsockopt()”设置它。
答案 1 :(得分:4)
关闭它。我记得;
close(fd);
答案 2 :(得分:4)
某些套接字库允许您专门拒绝传入连接。例如:GNU's CommonC++: TCPsocket Class有一个reject方法。
BSD套接字没有此功能。您可以接受连接,然后立即关闭,同时让套接字保持打开状态:
while (running) {
int i32ConnectFD = accept(i32SocketFD, NULL, NULL);
while (noConnectionsPlease) {
shutdown(i32ConnectFD, 2);
close(i32ConnectFD);
break;
}
}
答案 3 :(得分:2)
根据您编辑的问题版本,我不确定您是否必须“取消”或关闭()。我想到了两个选择:
1)在调用listen()之后,实际上不会接受连接,直到(逻辑上足够)调用accept()。您可以通过简单地忽略套接字活动并推迟任何accept()来“取消”,直到您为它们做好准备。任何入站连接都会尝试积压到在侦听模式下打开端口时创建的队列。一旦堆栈中的积压队列已满,就会在地板上放下进一步的连接尝试。当您使用accepts()恢复时,您将快速将待办事项出列,并为更多连接做好准备。
2)如果您确实希望端口暂时显示为完全关闭,则可以动态地将内核级别数据包筛选器应用于端口,以防止入站连接尝试到达网络堆栈。例如,您可以在大多数* nix平台上使用Berkeley Packet Filter(BPF)。也就是说,您希望使用平台的防火墙功能丢弃进入感兴趣端口的入站数据包。当然,这取决于平台,但这是一种可能的方法。
答案 4 :(得分:2)
我认为这不是向上游负载均衡器发出信号的好方法。在邮件通过之前,它必须实际向服务器发送一些连接 - 这些连接可能会被拒绝。
同样,当您关闭侦听套接字时,任何挂起的连接都将在没有数据的情况下关闭。
如果要向上游负载均衡器发出信号,则应该有一个协议来执行此操作。不要试图滥用TCP来做到这一点。
幸运的是,如果客户端是普通的Web浏览器,那么您可以侥幸逃脱 - 只需关闭套接字通常会导致它们对用户透明地重试(到某一点)。
答案 5 :(得分:1)
没有明确的方法可以解开!
您可以close(fd)
或shutdown(fd, how)
fd is the socket file descriptor you want to shutdown, and how is one of the following:
0 Further receives are disallowed
1 Further sends are disallowed
2 Further sends and receives are disallowed (like close())
答案 6 :(得分:0)
在基本级别,套接字是打开的还是关闭的(我们将忽略TCP / IP状态图的细节)。
如果您的套接字已关闭,则没有任何内容可以向其发送数据。如果它是打开的,那么TCP / IP堆栈将接受并确认传入的数据,直到它的缓冲算法“足够!”。此时,将不会确认更多数据。
我可以看到两个选择。当你想要“unlisten”时关闭()套接字,并在以后重新打开它 - 使用带有SO_REUSEADDR标志的setsockopt()允许你在TIME_WAIT2到期之前重新绑定到众所周知的端口。
另一个选择是保持套接字打开,但在你“忙碌”时根本不接受它。假设您对请求有一个应用程序级别的确认,您的负载均衡器会意识到它没有得到响应并采取相应的行动。
答案 7 :(得分:0)
根据您编辑的问题,这是一种相当丑陋的方法:
使用正常的待办事项打开一个用于收听的套接字。继续进行。
如果要“关闭”,请打开积压为1且SO_REUSEADDR的第二个。关闭第一个。准备好恢复时,再做另一个套接字与一个正常积压的套接字。
从你正在关闭的套接字中排出接受队列的挑剔细节将成为杀手。可能足以让这种方法无法实现。
答案 8 :(得分:0)
我不一定认为这是个好主意,但是......
您可以第二次拨打电话。 POSIX规范没有说不。当你想要“unlisten”时,也许你可以第二次用backlog参数0来调用它。
在使用0的积压调用listen时会发生什么似乎是实现定义的。 POSIX规范说可能允许接受连接,这意味着如果backlog参数为0,某些实现可能会选择拒绝所有连接。但是,当您通过时,您的实现将选择一些正值在0(可能是1或SOMAXCONN)。
答案 9 :(得分:0)
答案 10 :(得分:0)
您已经通过套接字API获得了无法做到这一点的答案。
您可以使用其他操作系统方法(即Host firwewall / iptables / ipfilter)来设置临时拒绝规则。
我发现大多数负载均衡器在识别连接问题的可能性方面有限(大多数只在连接探测中识别RST,而不是作为合法连接尝试的答案。)
无论如何,如果您受到检测到不可用性的探测的限制,您可以设置一个应用程序级别探测器来执行HTTP请求或FTP登录,或者如果您在接受后只是关闭它将识别它们。它甚至可以解释像“500 service not available”这样的错误消息,这对我来说似乎更干净。使用SNMP,某些负载均衡器也可以将结果用作加载提示。