/*==============================================================*/   
/* Object name:    服务器端程序                               */         
/* DBMS name:      Delphi 7                                     */   
/* Created on:     2006-09-13 21:00:00                          */   
/*==============================================================*/   
  
procedure TfrmMain.FormCloseQuery(Sender: TObject;   
var CanClose: Boolean);   
begin  
inherited;   
ComServer.UIInteractive:=False;   
if Not frmDMServer.adoConMain.Connected then  
    exit;   
if frmDMServer.qryClientStatus.Active then  
if frmDMServer.qryClientStatus.RecordCount > 0 then  
    begin  
      if (Application.MessageBox('关闭中间层系统将导致所有客户端无法连接,你确定需要关闭中间层系统吗?', '确认', MB_YESNO + MB_ICONQUESTION) = IDNO) then  
        canClose := false  
      else  
        try DisConnectAll(); except end;   
    end  
    else  
    begin  
      if (Application.MessageBox('您确定需要关闭中间层系统吗?', '确认', MB_YESNO + MB_ICONQUESTION) = IDNO) then  
        canClose := False;   
    end;   
end;   
  
  
procedure TfrmMain.DisConnect;   
var  
I: Integer;   
begin  
i := TStringGrid(ClientGrid).Row;   
try  
    sskServer.Socket.Connections[i - 1].SendText(c_Disconnect);   
    sskServer.Socket.Connections[i - 1].Close;   
    frmDMServer.qryClientStatus.Delete;   
except  
end;   
with frmDMServer.qryClientStatus do  
     if Active then Requery Else Open;   
end;   
  
procedure TfrmMain.DisConnectAll;   
var  
h: Integer;   
begin  
if frmDMServer.qryClientStatus.RecordCount > 0 then  
begin  
    for h := 0 to frmDMServer.qryClientStatus.RecordCount - 1 do  
    begin  
      try  
        sskServer.Socket.Connections[h].SendText(c_Disconnect);   
        sskServer.Socket.Connections[h].Close;   
  
        frmDMServer.qryClientStatus.Delete;   
      except  
      end;   
    end;   
  
    with frmDMServer.qryClientStatus do  
      if Active then Requery else Open;   
end;   
end;   
  
procedure TfrmMain.acDisSelectExecute(Sender: TObject);   
begin  
inherited;   
if (Application.MessageBox('你确定要断开当前客户连接?', '确认', MB_YESNO + MB_ICONQUESTION) = IDYES) then  
    DisConnect();   
if frmDMServer.qryClientStatus.Fields[1].AsString = '' then  
begin  
    acDisSelect.Enabled := false;   
    acDisall.Enabled := false;   
    acSendMessage.Enabled := false;   
    acReceiptMessage.Enabled := false;   
end;   
end;   
  
procedure TfrmMain.acDisAllExecute(Sender: TObject);   
begin  
inherited;   
if (Application.MessageBox('你确定要断开所有客户连接?', '确认', MB_YESNO + MB_ICONQUESTION) = IDYES) then  
    DisConnectAll();   
  
if frmDMServer.qryClientStatus.Fields[1].AsString = '' then  
begin  
    acDisSelect.Enabled       := false;   
    acDisall.Enabled          := false;   
    acSendMessage.Enabled     := false;   
    acReceiptMessage.Enabled  := false;   
end;   
end;   
  
  
procedure TfrmMain.sskServerClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);   
begin  
inherited;   
case ErrorEvent of  
    eeConnect:   
      Application.MessageBox('连接错误!', '信息', MB_OK + MB_ICONINFORMATION);   
    eeSend:   
      if bSendError then  
        Application.MessageBox('信息发送错误!', '信息', MB_OK + MB_ICONINFORMATION);   
    eeReceive:   
      Application.MessageBox('信息接收错误!', '信息', MB_OK + MB_ICONINFORMATION);   
    eeLookup:   
      Application.MessageBox('查找错误!', '信息', MB_OK + MB_ICONINFORMATION);   
end;   
ErrorCode := 0;   
end;   
/*==============================================================*/   
/* Object name:    客户端程序                                */         
/* DBMS name:      Delphi 7                                     */   
/* Created on:     2006-09-13 21:00:00                          */   
/*==============================================================*/   
procedure TfrmDMClient.cstLinkError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);   
begin  
case ErrorEvent of  
    eeConnect:   
      Application.MessageBox(PChar('远程连接错误'+#13#10+'请尝试重新启动中间层和SCKTSRVR!'), '警告', MB_ICONSTOP);   
    eeSend:   
      Application.MessageBox(PChar('发送错误...'), '警告', MB_ICONSTOP);   
    eeReceive:   
      Application.MessageBox(PChar('接收错误...'), '警告', MB_ICONSTOP);   
    eeDisconnect:   
      Application.MessageBox(PChar('断开错误...'), '警告', MB_ICONSTOP);   
    eeLookup:   
      Application.MessageBox(PChar('查找错误...'), '警告', MB_ICONSTOP);   
end;   
ErrorCode:=0;   
end;   
  
//关闭所有窗体   
procedure TfrmMain.muiWindowsCloseAllFormClick(Sender: TObject);   
begin  
CloseAllForm(Self);   
end;   
  
//退出系统   
procedure TfrmMain.muiExitClick(Sender: TObject);   
begin  
Close;   
end;   
  
//注销   
procedure TfrmMain.muiReLoginClick(Sender: TObject);   
begin  
if (Application.MessageBox('你确定要注销此系统吗?', '确认', MB_YESNO + MB_ICONQUESTION) = IDYES) then  
begin  
    if Assigned(frmDMClient) then  
    begin  
      if frmDMClient.cstLink.Socket.Connected then  
      begin  
        frmDMClient.cstLink.Socket.SendText(c_Close);   
      end;   
    end;   
    muiWindowsCloseAllFormClick(Sender);//关闭所有窗体   
    if Assigned(frmGuide) then frmGuide.Close;     //关闭导航   
    proLogin(1);//注销   
end;   
end;   
//窗体关闭   
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);   
begin  
if not bMainClose then  
    if (Application.MessageBox('你确定要退出此系统吗?', '确认', MB_YESNO + MB_ICONQUESTION) = IDYES) then  
    begin  
      CloseAllForm(Self);   
      frmDMClient.cstLink.Active:=false;   
      if Assigned(frmDMClient) then  
      begin  
        if frmDMClient.cstLink.Socket.Connected then  
        begin  
          frmDMClient.cstLink.Socket.SendText(c_Close);   
        end;   
        frmDMClient.Free;   
      end;   
      Action:=caFree;   
    end  
    else  
      Action:=caNone;   
end;   
  
这是我的三层结构的客户端和中间层的部份退出代码
现在的问题是:无论是客户端的非正常退出还是中间层的非正常关闭,都会导致所有的客户端再次登录时显示“断开错误”,其实主要的原因是客户端和中间层的退出机制有问题,没有对异常的正常处理,当中间层或是客户端当机或是直接关机而并未正常注销退出程序时用户信息未正常清除。请高手帮忙改一下,并且最好在中间层能给加一个心跳机制~~~~
高人现身吧