读书人

TServerSocket和TClientSocket做的C/S

发布时间: 2012-02-14 19:19:19 作者: rapoo

TServerSocket和TClientSocket做的C/S程序,网络断开,断电等的问题
TServerSocket和TClientSocket做的C/S程序,如果ClientSocket端的计算机突然断电,当机,网线断开,TServerSocket如果才能快速的知道,反之,如果是TServerSocket端的计算机突然断电,当机,网线断开,TClientSocket如果才能快速的知道.
请高手帮忙.

如有DEMO发给我ybbhond@163.com

[解决办法]
自己做高频的心跳。。。
[解决办法]
这两个控件很少用
在服务器程序退出的情况下在ClientSocketDisconnect,ServerSocketClientDisconnect这个事件里可以判断,如果断电,网络断开可能用这个是判断不出来
用TIdIcmpClient定时ping主机,断电,网络不通的话都可以检测出来
[解决办法]
控件例子

unit Main;

interface

uses
{$IFDEF Linux}
QGraphics, QControls, QForms, QDialogs, QStdCtrls, QExtCtrls,
{$ELSE}
windows, messages, graphics, controls, forms, dialogs, stdctrls, extctrls,
{$ENDIF}
SysUtils, Classes, IdIcmpClient, IdBaseComponent, IdComponent, IdRawBase, IdRawClient;


type
TfrmPing = class(TForm)
lstReplies: TListBox;
ICMP: TIdIcmpClient;
Panel1: TPanel;
btnPing: TButton;
edtHost: TEdit;
procedure btnPingClick(Sender: TObject);
procedure ICMPReply(ASender: TComponent; const ReplyStatus: TReplyStatus);
private
public
end;

var
frmPing: TfrmPing;

implementation
{$IFDEF MSWINDOWS}{$R *.dfm}{$ELSE}{$R *.xfm}{$ENDIF}

procedure TfrmPing.btnPingClick(Sender: TObject);
var
i: integer;
begin
ICMP.OnReply := ICMPReply;
ICMP.ReceiveTimeout := 1000;
btnPing.Enabled := False; try
ICMP.Host := edtHost.Text;
for i := 1 to 4 do begin
ICMP.Ping;
Application.ProcessMessages;
//Sleep(1000);
end;
finally btnPing.Enabled := True; end;
end;

procedure TfrmPing.ICMPReply(ASender: TComponent; const ReplyStatus: TReplyStatus);
var
sTime: string;
begin
// TODO: check for error on ping reply (ReplyStatus.MsgType?)
if (ReplyStatus.MsRoundTripTime = 0) then
sTime := ' <1 '
else
sTime := '= ';

lstReplies.Items.Add(Format( '%d bytes from %s: icmp_seq=%d ttl=%d time%s%d ms ',
[ReplyStatus.BytesReceived,
ReplyStatus.FromIpAddress,
ReplyStatus.SequenceId,
ReplyStatus.TimeToLive,
sTime,
ReplyStatus.MsRoundTripTime]));
end;

end.
[解决办法]
几次ping 不通的话就断开连接从新连,有个缺点,可能防火墙会设置禁止ping命令,ping不通其实网络是通的,这个要具体分析了,或者在协议里自己加心跳校验
[解决办法]
打开TCP/IP的KeepAlive机制,把检测超时设短点,就可以自动检测。
[解决办法]
通用做法是在协议里增加双向的心跳命令
[解决办法]
用indy或者socket api吧,你这两个控件我不熟悉,没找到关于心跳方面的用法,IdSocket有心跳机制
procedure SetSockOpt(level: Integer; optname: Integer; optval: PChar; optlen: Integer);

Parameters

level: Integer

Option level Id_SOL_SOCKET, Id_IPPROTO_TCP, or Id_IPPROTO_IP.


optname: Integer

Socket option to receive the option value.


optval: PChar

Value for the requested option.


optlen: Integer

Length of the option value buffer.


例子我就不贴了
[解决办法]
//使用keepalive
unit utils_socketc;


interface
uses IdStackConsts,IdStackWindows,IdWinSock2;

const
IOC_IN =$80000000;
IOC_VENDOR =$18000000;
SIO_KEEPALIVE_VALS =IOC_IN or IOC_VENDOR or 4;
type

tcp_keepalive=record
onoff:Longword;
keepalivetime:Longword;
keepaliveinterval:Longword;
end;


//设置KeepAlive用于检测线路是否中断
function SetKeepALive(const SockHandle:integer):Boolean;
implementation
uses typedefc,global_vspmc,showmsgc,inifilefuncv2;
function SetKeepALive(const SockHandle:integer):Boolean;
var
KeepAliveIn : tcp_keepalive;
KeepAliveOut : tcp_keepalive;
Status : Integer;
BytesReturned : Cardinal;
enkeepalive:boolean;
Akeepalivetime,Akeepaliveinterval:integer;
begin
Result:=false;
//是否启用KeepALive,默认为启用
inifilefuncv2.readsect_boolean_ini(GVspmConfig_ini,
cfg_globalcfg,cfg_enablekeepalive,enkeepalive,cfg_enablekeepalive_def);
if not enkeepalive then exit;
//默认发检测包间隔
inifilefuncv2.readsect_integer_ini(GVspmConfig_ini,
cfg_globalcfg,cfg_keepalivetime,Akeepalivetime,cfg_keepalivetime_def);

inifilefuncv2.readsect_integer_ini(GVspmConfig_ini,
cfg_globalcfg,cfg_keepaliveinterval,Akeepaliveinterval,cfg_keepaliveinterval_def);

KeepAliveIn.onoff:=1;
//发送检测包间隔
KeepAliveIn.keepalivetime:=Akeepalivetime;
//回应超时,默认情况下,如果出现超时,Windows将重新发送检测包,直到5次全部失败。
KeepAliveIn.keepaliveinterval:=Akeepaliveinterval;
Status:=WSAIoctl(SockHandle, SIO_KEEPALIVE_VALS,
@KeepAliveIn, SizeOf(KeepAliveIn),
@KeepAliveOut, SizeOf(KeepAliveOut),
@BytesReturned, nil, nil);
if Status <> 0 then
begin
showmsgc.showNormal_msg( 'SetKeepAlive error ', ' ');
exit;
end;
Result:=true;
end;

end.

读书人网 >.NET

热点推荐