用idTCPserver写的server程序退出时,出现异常的问题(底下有client,且没有断开连接);问怎样处理可以避免出现异常!!

xinqingbucuo 2005-02-01 08:13:31
用idTCPserver写的server程序退出时,出现异常的问题(底下有client,且没有断开连接);问怎样处理可以避免出现异常!!
...全文
412 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ly_liuyang 2005-02-01
  • 打赏
  • 举报
回复
修改Indy的PAS源码就可以解决问题,关闭前Active:=false就可以了

procedure TIdTCPServer.SetActive(AValue: Boolean);
var
i: Integer;
LListenerThread: TIdListenerThread;
begin
// SG 28/11/01: removed the "try..finally FActive := AValue; end;" wrapper
// SG 28/11/01: It cause the component to be locked in the "active" state, even if
// SG 28/11/01: the socket couldn't be bound.
if (not (csDesigning in ComponentState)) and (FActive <> AValue)
and (not (csLoading in ComponentState)) then begin
if AValue then begin
// InitializeCommandHandlers must be called only at runtime, and only after streaming
// has occured. This used to be in .Loaded and that worked for forms. It failed
// for dynamically created instances and also for descendant classes.
if not FCommandHandlersInitialized then begin
FCommandHandlersInitialized := True;
InitializeCommandHandlers;
end;
// Set up bindings
if Bindings.Count = 0 then begin
Bindings.Add;
end;

// Set up ThreadMgr
ThreadMgr.ThreadClass := ThreadClass;

// Setup IOHandler

if not Assigned(FIOHandler) then begin
IOHandler := TIdServerIOHandlerSocket.Create(self);
FImplicitIOHandler := true;
end;
// Update reply texts for "global" replies
ReplyTexts.UpdateText(ReplyUnknownCommand);
ReplyTexts.UpdateText(MaxConnectionReply);
// Set up listener threads

IOHandler.Init;
i := 0;
try
while i < Bindings.Count do begin
with Bindings[i] do begin
AllocateSocket;
if (FReuseSocket = rsTrue) or ((FReuseSocket = rsOSDependent) and (GOSType = otLinux))
then begin
SetSockOpt(Id_SOL_SOCKET, Id_SO_REUSEADDR, PChar(@Id_SO_True), SizeOf(Id_SO_True));
end;
Bind;
end;
Inc(i);
end;
except
Dec(i); // the one that failed doesn't need to be closed
while i >= 0 do begin
Bindings[i].CloseSocket;
Dec(i);
end;
FActive := True;
SetActive(False); // allow descendants to clean up
raise;
end;
FListenerThreads := TThreadList.Create;
for i := 0 to Bindings.Count - 1 do begin
Bindings[i].Listen(FListenQueue);
LListenerThread := TIdListenerThread.Create(Self, Bindings[i]);
FListenerThreads.Add(LListenerThread);
LListenerThread.Start;
end;
FActive := True; // fixed by Liu Yang 2004.7.24

end else begin
TerminateListenerThreads;
FActive := false; // fixed by Liu Yang 2004.7.24
// Tear down ThreadMgr
try
TerminateAllThreads;
finally
if ImplicitThreadMgr and TIdThreadSafeList(Threads).IsCountLessThan(1) then begin // DONE -oAPR: BUG! Threads still live, Mgr dead ;-(
FreeAndNil(FThreadMgr);
FImplicitThreadMgr := False;
end;
end;//tryf
end;
end;
FActive := AValue;
end;

http://lysoft.7u7.net
ball_24 2005-02-01
  • 打赏
  • 举报
回复
>无论客户端还是服务器端,都不能无缘无故的断开,必须先通知对方一下,然后都断开。
>就像打电话,一头什么都没说就挂了,那头就会出错了,要说“再见”后再挂。

反对!
xinqingbucuo 2005-02-01
  • 打赏
  • 举报
回复
自己顶一下,期待尽快回复,
xinqingbucuo 2005-02-01
  • 打赏
  • 举报
回复
是不是如果断开连接,不许有自己的约定,比如我的server下线是发goodbye,那边也发goodbye,是不是我必须自定义,这些东西才行,indy中没有现成的函数之类的东西供我调用(我的 client是一个硬件设备,我不肯能去规定它什么东西),新手请多指教!!
crbb 2005-02-01
  • 打赏
  • 举报
回复
>无论客户端还是服务器端,都不能无缘无故的断开,必须先通知对方一下,然后都断开。
>就像打电话,一头什么都没说就挂了,那头就会出错了,要说“再见”后再挂。


呵呵!我打电话经常性的 不说再见就挂
cjf1009 2005-02-01
  • 打赏
  • 举报
回复
无论客户端还是服务器端,都不能无缘无故的断开,必须先通知对方一下,然后都断开。

就像打电话,一头什么都没说就挂了,那头就会出错了,要说“再见”后再挂。
cjf1009 2005-02-01
  • 打赏
  • 举报
回复
http://community.csdn.net/Expert/topic/3511/3511314.xml?temp=.5837976

这是我以前参与讨论的一个帖子,希望对你有用
yuvotesyg518 2005-02-01
  • 打赏
  • 举报
回复
服务器建立与一个客户端的连接时,记录连接线程,假设为:lcThread
需要断开时,可调用如下的代码:
TIdPeerThread(lcThread).Connection.Disconnect;

另外,你说的这种异常好像只是在调试的时候才会出现吧??
如果是那样的话,可以不用理它。
用外国程序员的说法就是,那是正常的异常!!
xinqingbucuo 2005-02-01
  • 打赏
  • 举报
回复
to 农民程序员,我的程序怎么加上tcp控件之后好像跟死掉了一样呀,我以为是程序的毛病,后来我去掉了,就好了,不知道为什么?
to liuyang,请问有不改indy源程序的方法吗?
比如我可以在自己的程序中,先将连接线程去掉可以吗,怎么做???

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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