IdTCPClient 资源泄漏
南郁 《白话C++之练功》、《练武》 书籍作者 2006-01-25 04:21:52 this->IdTCPClient1->Host = "192.168.0.121";
this->IdTCPClient1->Port = 6002;
try
{
this->IdTCPClient1->Connect(1000);
}
catch(const EIdAlreadyConnected& )
{
}
catch(...)
{
}
上面代码,当this->IdTCPClient1->Connect(1000);连接失败(故意不开服务端,
就可以。)然后异常,然后被捕获(在IDE环境,会弹出异常提示窗口,不必在意)。
通过“Windows任务管理器” (Ctrl+Alt+Del,调出),观察,每当上面代码运行一遍,
程序所占用的 “句柄数”,就会多出1来:第1次可能会多出好几个,正常的,以后执行时
(一次次按Button),就会稳步增1 (偶尔也会多出5或4,但会很快吐还4,3个句柄).
=====================
Indy 9.0.17 或 Indy 9.0.18. C++Builder 6,打了补丁4.
没有Delphi环境。但我想这是Indy自身的事。
=====================
虽然只是吃了一个句柄(Handle)。但是,我写的是服务,连续跑了4天,就吃了4万多个句柄。
句柄是OS资源呢。。。惨。哪位高人有Delphi,帮忙跟踪一下Indy的源代码,告诉我具体吃掉
那个句柄的事,是在哪里?
我做了测试。delete 掉 IdTCPClient1,这些句柄也不会放出,可见这个句柄应是成了无主
的了。
查了一下Indy的源代码:
//IdTCPClient.pas
procedure TIdTCPClient.Connect(const ATimeout: Integer = IdTimeoutDefault);
begin
// Do not call Connected here, it will call CheckDisconnect
if IOHandler <> nil then begin
if IOHandler.Connected then begin
raise EIdAlreadyConnected.Create(RSAlreadyConnected);
end;
end else begin
IOHandler := TIdIOHandlerSocket.Create(Self);
IOHandler.OnStatus := OnStatus;
FFreeIOHandlerOnDisconnect := True;
end;
try
IOHandler.Open;
ResetConnection;
// Socks support
IOHandler.ConnectClient(Host, Port, BoundIP, BoundPort, BoundPortMin, BoundPortMax, ATimeout);
if Assigned(Intercept) then begin
Intercept.Connect(Self);
end;
DoStatus(hsConnected, [Host]);
DoOnConnected;
except
// This will free IOHandler
DisconnectSocket;
raise;
end;
end;
因为IdTCPClient1 没有被delete掉,所以IOHandler只Create 了一回。应不是它的事。
由于故意让它连接不上,来导致抛出异常,所以我想是不是DisconnectSocket这个过程
里没有释放什么东西?查找源代码,找到:
procedure TIdSocketHandle.CloseSocket(const AResetLocal: boolean = True);
begin
if HandleAllocated then begin
// Must be first, closing socket will trigger some errors, and they
// may then check (in other threads) Connected, which checks this.
FHandleAllocated := False;
GStack.WSShutdown(Handle, Id_SD_Default);
// SO_LINGER is false - socket may take a little while to actually close after this
GStack.WSCloseSocket(Handle);
end;
end;
会是WSShutdown 或 WSCloseSocket 的问题?大家帮忙看看。谢谢了。