Socket应用程序中,客户机当机了,怎么办?(100分)

W

wrench

Unregistered / Unconfirmed
GUEST, unregistred user!
在编程中,如果ClientSocket端的计算机突然掉电或重新启动,ServerSocket
端的程序怎样才能捕捉到这一事件的发生?当ClientSocket端的计算机突然掉
电或重新启动时,OnClientDisconnect事件并不发生,有关的Socket对象的
Connected属性依然为true.请各位大虾不吝赐教!
 

我觉得这可以这样解决:设定一个时间长度,当客户端没有动静的时间超过了这

一长度,你就当作客户机已断开。
 
SERVER的OnClientError里面应该捕获的到 :)
 
TErrorEvent = (eeGeneral, eeSend, eeReceive, eeConnect, eeDisconnect, eeAccept);

TSocketErrorEvent = procedure (Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer
) of object;
这几种ERROR类型应该够用了吧!
 
to wuyi老兄:
CLIENT并不一定时时都在和SERVER大交道.
如果CLIENT的使用者接个电话,你就给段开了
恐怕霸道了点吧!
 
to 唐晓锋:

我并没要求“CLIENT一定时时都在和SERVER打交道”,难道说client有30分钟

没跟SERVER通过讯,我把它断开会得“恐怕霸道了点”这项帽子吗?
 
to wuyi:
老兄别生气,我只是觉得不太好而已
"恐怕霸道了点"开玩笑吗 *_-
 
Client broadcast message to server timer.If the server failed to
receive the client's broadcast,it can regard the client is down.
 
to 唐晓峰:
对此现象,SERVER的OnClientError事件没有反应
to och.ocx:
若有很多的客户机与服务器相连,怎样才能判断出具体是哪一个客户当机了?
 
同志们,我记得这个问题以前讨论过,因此就没发言。
怎么搞了这么长时间还没搞定呢?

Wrench:

出现这个问题是因为你没有实际利用Winsock的多线程特性
SeverSocket仅仅是用于侦听的Socket,而不是负责通讯的。
当他接收到一个连接请求时,就会生成一个新的Socket负责通讯,
这个Socket就是ServerSocketAccept(Sender: TObject; Socket: TCustomWinSocket);
中的Socket参数。

因此,要实现一对多的通讯,必须要自己处理多个Client的请求,
这里只给一个例子,就是你需要的每当Client宕机时会触发OnError事件:

TForm1 = class(tform)
procedure onConnectionError(Sender:TObject;Socket:TCustomWinSocket;
ErrorEvent:TErrorEvent;var errorCode:integer);
//定义在这里,使之成为TNotifyEvent
...
public
private
end;

procedure TForm1.ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
var
i:integer;
begin
socket.onErrorEvent := onConnectionError;
...
end;

procedure TForm1.onConnectionError(Sender:TObject;Socket:TCustomWinSocket;
ErrorEvent:TErrorEvent;var errorCode:integer);
begin
//Error Handling
end;

 
可模仿IRC方式, 定时由server发出一个特定的ping信号, 如果client 有n次(n自己
定义)没有响应则认为是断线.
或者直接调用ICMP的PING也行.
只要定时做个循环轮流ping每个client就成. (不占多少系统资源和带宽)
 
首先声明,我只讨论ctNonBlocking类型的Socket,因为我以前
曾对此做过测试,在OnClientError确实能截获该错误,错误
信息是连接超时,而且不用发数据去触发它自己就能检测到,
只不过时间比较长,一般会在10分钟之内调用OnClientError。
 
I try to be fair, :)
 
按dwwang的方法试过,但为什么没有效果?
 

Similar threads

S
回复
0
查看
745
SUNSTONE的Delphi笔记
S
S
回复
0
查看
625
SUNSTONE的Delphi笔记
S
顶部