我正在使用Windows 10 1903,带有Indy 10.6.2.5366的Delphi Rio 10.3.3。
我正在将使用TServerSocket的旧Windows Service应用程序升级到Indys TIdTCPServer。主要原因是我必须向应用程序添加IPv6支持。
我遇到的问题是TIdTCPServer吃了线程。对于与TIdTCPServer的每个连接,都会分配一个新线程(应如此),但是当客户端断开连接时,该线程不会关闭。
如果我同时连接两个客户端,则IdTCPServer1.Contexts.Locklist.Count = 2和OnExecute事件应在每个“周期”触发两次。如果然后我断开一个客户端的连接,则IdTCPServer1.Contexts.Locklist.Count = 1,则OnExecute每个周期仅触发一次(也应如此),但两个线程仍在运行。 (我使用Windows taskmanager看到了这一点)
我构建了一个简单的测试应用程序,该应用程序以几秒钟的间隔随机连接和断开连接,启动了5个程序,当到达大约150个线程时,我的服务崩溃了。
这是我的OnExecute事件:
procedure T#############.IdTCPServer1Execute(AContext: TIdContext);
var
incomestring: string;
begin
try
if AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
AContext.Connection.IOHandler.CheckFordataOnSource(100);
AContext.Connection.IOHandler.CheckForDisconnect;
if AContext.Connection.IOHandler.InputBufferIsEmpty then
Exit;
end;
incomestring:= AContext.Connection.IOHandler.InputBufferAsString(en8bit);
if length(trim(incomestring)) = 0 then
begin
exit;
end;
DataRead(incomestring,AContext); // Send data be processed
except
on E: Exception do
begin
if E is EIdException then
raise // <- re-raise only Indy-specific exceptions end;
else
begin
inc(ErrorCount);
Logg('Error in IdTCPServer1Execute: ' + E.Message,ltError,AContext);
end;
end;
end;
end;
我使用InputBufferAsString的原因是我无法控制连接到服务器的客户端。因此,结尾不一定总有CR或LF(如ReadLn所希望的)。而且,客户端会在断开连接之前保持与服务器的连接数小时。