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 的问题?大家帮忙看看。谢谢了。
...全文
353 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
sczyq 2006-02-21
  • 打赏
  • 举报
回复
只是 TIdTCPClient 连接到同一个 Application 内的 TIdTCPServer 时会有问题。好在一般不会使用这种情况。
sczyq 2006-02-21
  • 打赏
  • 举报
回复
使用 Indy10 吧,我用了很正常,内存、句柄、线程等均能回到正常。


注:BCB 2006 + Indy10
南郁 2006-02-21
  • 打赏
  • 举报
回复
我是用9.0.18.从17又升级了一次的。

好像是和Windows的补丁有关。有哪位遇见过。
constantine 2006-02-15
  • 打赏
  • 举报
回复
我在2003 用9.0.18测试不会

不过我看过过程 他不是马上都释放掉的
有一个要等一下才释放,你最好看清楚,不过也不用等很久,大概1秒左右

确定你用的是9.0.18
我不懂电脑 2006-02-15
  • 打赏
  • 举报
回复
我这还是比较正常的。
南郁 2006-01-25
  • 打赏
  • 举报
回复
to: FengSC(小猪好好跑 :) 不是啊,程序运行三天,这句柄数就一天天慢慢地长去了。另外,就算把IdTCPClient1 对象delete之后,这些句柄也还占着。

刚才又做了测试,让IdTCPClient1->Connect()成功连上,(故意开个服务端监听指定的端口),然后再调用一句 IdTCPClient1->Disconnect()。这句柄一加一减之间,还是少还一个。

看来这是一个Indy本应很明显的BUG啊。怎么没有人发现。
FengSC 2006-01-25
  • 打赏
  • 举报
回复
我猜是等一段时间后就会释放。

1,316

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧