VC写的Server程序关闭后,Delphi写的IdTcpClient的连接状态怎么还保持着呢。 ( 积分: 50 )

  • 主题发起人 主题发起人 cocainy
  • 开始时间 开始时间
C

cocainy

Unregistered / Unconfirmed
GUEST, unregistred user!
我碰到这样一个问题,就是当VC写的Server程序关闭后,怎么IdTcpClient的连接还保持着呢<我用F7跟踪的时候,总是连接着:( >,另外我在运行->cmd->netstat -a -n 查看连接状态显示已经断开!!!我贴上源代码,网富翁之点。
//检测是否连接的线程
TThreadCheckConn = class(TThread)
private
{}
protected
procedure Execute; override;
procedure ShowConnState;
end;
procedure TThreadCheckConn.Execute;
begin
Self.FreeOnTerminate:=True;
repeat
//Synchronize(Self.ShowConnState);
Self.ShowConnState
until Self.Terminated;
end;

procedure TThreadCheckConn.ShowConnState;
var
i : integer;
begin
//检查IdTcpClient的连接状态,如果没有连接,则连接
try
{****** 下面的这个判断怎么在Server程序关闭后却总是为真呢 *******}
if not (FrmMain.IdTCPClient.Connected) then
FrmMain.IdTCPClient.Connect(500);
except
FrmMain.StatusBar.Panels[2].Text:='与采集端连接失败'
end;
end;
 
我碰到这样一个问题,就是当VC写的Server程序关闭后,怎么IdTcpClient的连接还保持着呢<我用F7跟踪的时候,总是连接着:( >,另外我在运行->cmd->netstat -a -n 查看连接状态显示已经断开!!!我贴上源代码,网富翁之点。
//检测是否连接的线程
TThreadCheckConn = class(TThread)
private
{}
protected
procedure Execute; override;
procedure ShowConnState;
end;
procedure TThreadCheckConn.Execute;
begin
Self.FreeOnTerminate:=True;
repeat
//Synchronize(Self.ShowConnState);
Self.ShowConnState
until Self.Terminated;
end;

procedure TThreadCheckConn.ShowConnState;
var
i : integer;
begin
//检查IdTcpClient的连接状态,如果没有连接,则连接
try
{****** 下面的这个判断怎么在Server程序关闭后却总是为真呢 *******}
if not (FrmMain.IdTCPClient.Connected) then
FrmMain.IdTCPClient.Connect(500);
except
FrmMain.StatusBar.Panels[2].Text:='与采集端连接失败'
end;
end;
 
自己顶,怎么没有人回答阿
 
富翁阿,你就开开眼吧。

今天是最后的一天啊。马上要交稿了啊。

那位路过,如果能够给介绍个富翁,让俺去问问题,我也给分的阿
 
不要判断 FrmMain.IdTCPClient.Connected ,它会有延时的,我碰到过。
建议用TCPIP协议中的一些测试命令。
 
什么命令
 
我一直在线等待,请不吝赐教
 
hxb_leiyuan 说的很对, IdTCPClient.Connected 并不是每次都判断是非真正连接的
肯定有个延时, 你可以使用 Api 或 找下IdTCPClient 有没有直接检查的方法,自己找下代码,很简单的
 
这个方面我了解不多,抱歉
 
我也找了,可是没有找到的,我找了两天了。
API我也看了,没有关于某一个端口的断开的判断函数
 
兄弟,如果服务端也是indy做的,这非常容易实现。如果VC程序可以修改的话,这也很容易,比如让服务断增加一个时间服务,即客户端向服务器查询时间,服务器就返回它当前的时间给客户,如果没有返回则表明连接断了。如果VC程序做死了,这怎么办呢?我提供一些思路,一种方式:比如可以让客户端发送某些彼此都知道的指令(再详细些,就比如彼此通讯协议中的某些指令);第二种方式:服务器总是要侦听某个端口来与客户端通讯,这样就可以服务器端在做一个很小的程序,它不停的接受客户端的指令来做同一件事情,即查找查找服务器的指定端口上是不是有服务(netstat -a 命令就可以完成),如果没有了则表示服务程序断了,但这有一个问题,即该端口不应该被别的服务程序使用。
 
如果如果服务端也是indy做的,这样的问题很容易出现,因为indyserver在关闭时有时不关闭socket(这个BUG真要命!最新版的好一点)!无论如何!如果server不关闭socket,那么Client就不可能知道套接字已经关闭!,就象你突然把网线断了这样的非正常原因一样,TCP协议是不能马上做出反应的,如果要解决可以像楼上说的做个脉搏程序!
 
如果双方没有数据通信,一端断开连接的话,对端的os中的tcp层是知道的,但是对端的网络应用是不知道的,除非主动的去发送测试数据。假设A方和B方进行tcp通信。考虑以下情况:
A:等待接收B的数据,B:没有动作。则A断开连接,B是不知道的;如果B断开连接,则A的接收调用会失败,此时A可以感知B断开连接。
实际情况可能还要复杂。网络通信就像黑屋子里面的两个人交谈,你无法知道对方是否走开了,除非你试着询问。这样的话需要定义keepalive包。
假设B需要测试连接,则它需要定时发送keepalive包,然后根据实际情况进行判断(假设AB之间定义的通信协议包括流程是正确的):
(1)发送成功,收到A的keepalive回应(回应包):通信正常
(2)发送成功,没有收到A的keepalive回应:可能是A太忙无法回应;或者网络已断开,这种情况只能根据超时来判断,特别是internet通信,中间节点如路由器中断,AB是都不知道的
(3)发送失败:AB已断开
(4)发送成功,接收回应失败:AB已断开

还是那个黑屋子的例子,判断B走开的依据有很多
(1)B走开
(2)B不回答
(3)B回答了,A没有听到

总之一句话,判断的依据有os的tcp层的感知,还有应用的主动探测,指望某个控件主动提供状态报告是不行的,它的那种判断是根据你之前的通信结果得出的,并不是当前状态的反映。这个只能结合应用层的协议和通信流程才能解决,没有通用的。

 
后退
顶部