gpt4 book ai didi

delphi - IP黑名单TcpServer

转载 作者:行者123 更新时间:2023-12-03 15:47:43 26 4
gpt4 key购买 nike

如何限制每个 ip 的连接数?我试过这个代码 how to block unknown clients in indy (Delphi)但如果我的服务器被淹没,我将无法连接。 Remy 的代码只是阻止 CPU 使用 100% 并使用更多内存。但来自洪水的连接在 tcpserver 上仍然有效,我无法连接到服务器。所以我的问题是,如何在 onconnect 之前限制连接,使用 tcpserver 接受某些内容?也许 Hook 接受函数并尝试限制连接?

最佳答案

How i can limit the connections per ip?

你已经知道答案了,因为这正是the other code正在做。

if my server is flooded i can't connect.

其他代码的目的只是将客户端 IP 地址限制为最多 10 个同时连接,而不是防止洪水或降低 CPU/RAM 使用率。您无法阻止不需要的客户端连接到您的服务器,除非您停用服务器或设置其 MaxConnections 属性。除此之外,您所能做的就是尽快断开不需要的客户端,您可以在服务器的 OnConnect 事件中执行此操作。但是,如果您被淹没,则需要时间来处理,特别是如果您不断锁定和解锁服务器的Contexts列表,这最终将序列化服务器的内部线程。

洪水管理确实需要由防火墙或路由器/负载均衡器来处理,而不是在服务器应用程序本身中处理。如果这对您来说 Not Acceptable ,那么至少仅在 Windows 上,一个选项可能是编写一个自定义的 TIdServerIOHandlerStack 派生组件,该组件重写虚拟的 Accept() 方法调用WinSock的WSAAccept()函数,它提供了一个回调,您可以使用它在连接离开接受队列之前拒绝连接,因此 TIdTCPServer 不会看到它们。例如:

type
TMyServerIOHandler = class(TIdServerIOHandlerStack)
public
function Accept(ASocket: TIdSocketHandle; AListenerThread: TIdThread; AYarn: TIdYarn): TIdIOHandler; override;
end;

function MyConditionFunc(lpCallerId, lpCallerData: LPWSABUF; lpSQOS, lpGQOS: LPQOS; lpCalleeId, lpCalleeData: LPWSABUF; g: PGROUP dwCallbackData: DWORD_PTR): Integer; stdcall;
begin
if (the address stored in lpCallerId is blocked) then
Result := CF_REJECT
else
Result := CF_ACCEPT;
end;

type
TIdSocketHandleAccess = class(TIdSocketHandle)
end;

function TMyServerIOHandler.Accept(ASocket: TIdSocketHandle; AListenerThread: TIdThread; AYarn: TIdYarn): TIdIOHandler;
var
LIOHandler: TIdIOHandlerSocket;
LBinding: TIdSocketHandle;
LAcceptedSocket: TIdStackSocketHandle;
begin
Result := nil;
LIOHandler := TIdIOHandlerStack.Create(nil);
try
LIOHandler.Open;
while not AListenerThread.Stopped do
begin
if ASocket.Select(250) then
begin
LBinding := LIOHandler.Binding;
LBinding.Reset;
LAcceptedSocket := WSAAccept(ASocket.Handle, nil, nil, @MyConditionFunc, 0);
if LAcceptedSocket <> Id_INVALID_SOCKET then
begin
TIdSocketHandleAccess(LBinding).SetHandle(LAcceptedSocket);
LBinding.UpdateBindingLocal;
LBinding.UpdateBindingPeer;
LIOHandler.AfterAccept;
Result := LIOHandler;
LIOHandler := nil;
Break;
end;
end;
end;
finally
FreeAndNil(LIOHandler);
end;
end;

然后,您可以在激活服务器之前将 TMyServerIOHandler 的实例分配给 TIdTCPServer.IOHandler 属性。

关于delphi - IP黑名单TcpServer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42820313/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com