我的三层系统采用TSocketConnection连接中间层,之所以不采用TDcomConnection,是因为TSocketConnection配置比较简单(基本不需要配置),但是发现一个很头疼的问题:当网络不通时,TSocketConnection连接中间层到产生异常要发费很长的和段时间(10几分钟吧?)!这样我准备的碰到异常就连接其它应用服务器的代码根本起不了作用,用户以为是死机了,直接关掉了!
请问,当网络不通时,如何缩短TSocketConnection的超时时间?
请问,当网络不通时,如何缩短TSocketConnection的超时时间?
解决方案 »
- 刚回家办好结婚证回来上班,发红包给D友们。
- 三层结构,我写了一个简单的测试程序,为什么客户端再次取数据会出错?
- delphi如何修改系統時間
- 如何在FAstreport中给记录编一个序列号,每一次都是从1开始!
- 我想了三天没解决,请高手教我,关于屏蔽对话框。在线等,请。。。。。。
- 怎么使用BoundsChecker查看一个可执行文件的API调用顺序
- 轻松回答
- 使用哪个函数来取得某个字符特定长度的重复字符串?
- 为什么多层结构的主从表无法刷新子表?
- horlen(少爷的破拐杖),这1分是给你的,决不食盐!
- 佳能相机的SDK
- 在用ADO做DELPHI数据库方面得东西时不知道不觉中报了一个错,不知道怎么解决,请各位高手指教了!
》》》》》》》》》》》》》》》》》》
var
WSAData:TWSADATA;
begin
WSAStartup(2, WSAData);
if GetHostByName(PChar(AHost))=nil then
result:= false
else result:= true;
WSACleanup();
end;...
for I := 0 to ServerConns.Count -1 do
begin
if TestHost(ServerConns.Items[I].FServerN) then
with TServerItem(SmpBroker.Servers.Add) do
begin
ComputerName := ServerConns.Items[I].FServerN;
Port := ServerConns.Items[I].FPortID;
end;
end;
if SmpBroker.Servers.Count <= 0 then
begin
MsgBox('没有可用的中间层服务器!');
Exit;
end;
RmConn.Connected := true;
if not RmConn.Connected then
Exit;
可以用一个定时器,指定时间后还未连上就认为是超时
--------------------------------------------------
同一个进程中,这种状态定时器没法触发的.
如果用户指定的服务器名称不存在时,您如何处理呢?
我的系统做成用户可自定义连接服务器。
procedure TSocketTransport.SetConnected(Value: Boolean);你可以跟踪调试一下。。看哪儿花时间长。。
线程最好完全自己处理异常。想把它送给主线程很麻烦的,还容易出问题。
还可以把SOCKETCONNECTION放在子线程中连接,把主子线程角色对调。但你此后所有代码都得修改。
AConnthread: TConnthread;AConnthread := TConnthread.Create(SocketConnection1); //在线程中连接while not SocketConnection1.Connected do //等待连接结果
begin
sleep(100);
inc(i);
if i > 1000 then //100秒超时
begin
showmessge('连接超时!');
AConnthread.Terminate; //强行终止连接线程应该是可以的
AConnthread.Free;
Exit;
end;
end;不知行否?我还没试过,但是如果解决了连接的问题,那么如使用过程中网络断开又如何处理?
TSocketconnection是使用event select i/o 方式的SOCKET.当为FLASE的时候,
是使用的普通阻塞方式SOCKET.有一点重要的忘了问楼主,报的异常具体是什么?
你知道的,在服务器端需要运行Socket Server, 当运行之后它会在系统托盘中有一个图标,右击它的图标选择Properties ,在弹出的对话框中有一个称之为Timeout的框架,其中的Inactive Timeout 默认时是0,即无限长时间。你可以指定一定长度的时间以响应你的连接超时,记住是分钟数。
另外,我建议搂主使用SimpleObjectBroker以达到服务器容错和平衡负载的作用。
在数据单元中的uses 的SConnect改为mySConnect
改 InternalOpen 可以试试
FTransIntf := CreateTransport;
FTransIntf.SetConnected(True);
最后执行 ScktComp 单元的 TCustomWinSocket.DoOpen:procedure TCustomWinSocket.DoOpen;
begin
DoSetASyncStyles;
Event(Self, seConnecting);
CheckSocketResult(WinSock.connect(FSocket, FAddr, SizeOf(FAddr)), 'connect'); ////// 程序等在这一行上。因为执行的是一个 Block 模式的 connect,好像没有什么办法了。
FLookupState := lsIdle;
if not (asConnect in FAsyncStyles) then
begin
FConnected := FSocket <> INVALID_SOCKET;
Event(Self, seConnect);
end;
end;procedure TCustomWinSocket.DoSetAsyncStyles;
var
Msg: Integer;
Wnd: HWnd;
Blocking: Longint;
begin
Msg := 0;
Wnd := 0;
if FAsyncStyles <> [] then
begin
Msg := CM_SOCKETMESSAGE;
Wnd := Handle;
end;
WSAAsyncSelect(FSocket, Wnd, Msg, Longint(Byte(FAsyncStyles)));
if FASyncStyles = [] then
begin
Blocking := 0;
ioctlsocket(FSocket, FIONBIO, Blocking); ///// 进入 Block 模式
end;
end;
我试过了,FSupportCallbacks为真时碰到不能的情况要201秒,而FSupportCallbacks为假时只要21秒就有反应了,与telnet的时间差不多。
在主FORM 的OnCreate 事件里
如果输入错误地址马上就报错了.我觉的很奇怪procedure TFrm_Main.FormCreate(Sender: TObject);
var TmpRegistry:TRegistry;
ServerIp:string;
begin
OnLinePeople.Caption:='';
TestClient:=true;
try
dm:=Tdm.Create(nil);
except;
application.MessageBox('系统创建远程数据模块出错!请重新运行','致命错误',mb_iconerror+mb_ok);
application.Terminate;
end; TmpRegistry:=TRegistry.Create;
TmpRegistry.RootKey:=HKEY_LOCAL_MACHINE;
TmpRegistry.OpenKey('\Software\NewView Media\System Option',true);
ServerIp := TmpRegistry.ReadString('RemoteAddress');
TmpRegistry.CloseKey;
TmpRegistry.Free; if serverIp='' then
begin
application.MessageBox('系统检测到远程地址为空,点击"确定"后'+#13+'系统进行远程设置!','用户登录',mb_iconWarning+mb_ok);
winexec('ClientIp.exe',0);
application.Terminate;
end; dm.SocketConnection1.Host:=ServerIp;
Frm_main.Client.Host:=ServerIp;
try
Client.Active:=true;
dm.SocketConnection1.Connected:=true;
except
try
TestClient:=false;
Client.Free;
dm.SocketConnection1.Connected:=false;
Timer2.Enabled:=false;
application.MessageBox('服务器出错,请检测您输入的IP地址或者请咨询管理者!','用户登录',mb_iconWarning+mb_ok);
finally
dm.Free;
end;
Frm_ServerSet:=TFrm_ServerSet.Create(nil);
Frm_ServerSet.showmodal;
Frm_ServerSet.Free;
abort;
end;
end;