结构:Client(SocketConnection) + Server(RemoteDataModule ) + DataBase(sql server 2000)Server上维护一些测量程序名,以及对应的点位,和一些测量参数
Client上对测量仪器所测量的测量数据时实监控,用的是一个多线程.
       每次获取到数据文件,都会通过ClientDataSet传递到Server端.然后在Server端进行点位比对,数据检验,添加合格标志.
       再把这些信息通过OleVariant返回到Client.
Client的数量有16现在遇到的问题就是Client在使用过程中,经常无缘无故的死掉,而且重新登陆连接还是无法连接到Server.
我有打开scktsrvr.exe查看用户数,上面会有同一个用户的多个连接在上面,所以导致该用户无法再连接,只有把scktsrvr.exe重新启动以后,又没有问题,可以用几个小时,过后又是这样.
       
 
下面是我Server上RemoteDataModule中的两个函数
function TQPDMRDM.CheckAllAvriable(List: OleVariant;
  const prg_name: WideString): WideString;
var
  // a : Tdata;   
   str_sql: String;
   variable_name ,addflag: String;
  
   temp_str : String;
begin
    temp_str := '';    str_sql := 'SELECT * FROM v_variable WHERE FOLDER_NAME='''+ trim(prg_name)+'''';
    adoquery1.Close;
    adoquery1.SQL.Clear;
    adoquery1.SQL.Add(str_sql);
    adoquery1.Open;    ClientDataSet1.Data := List;
    if adoquery1.RecordCount > 0 then
    begin
       adoquery1.First;
       while not adoquery1.Eof do
       begin
         variable_name :=trim(adoquery1.fieldbyname('variable_name').AsString);
         if not ClientDataSet1.Locate('variable_name',variable_name,[]) then 
         begin//用比这更优的比对方法吗??
           if temp_str <> '' then
              temp_str := temp_str + ',';
           temp_str := temp_str  + variable_name;
         end;
         adoquery1.Next;
       end;
    end;
    ClientDataSet1.EmptyDataSet;
    adoquery1.Close;
    Result := temp_str;
end;
      
function TQPDMRDM.InsertAll(Ole_DataSet: OleVariant; const prg_name,
  computername: WideString): OleVariant;
var
   addflag :String;
   D_value : Double;
   s_Variable,S_datetime : String;
   ok_flag : Integer;
begin
try
 try
  cds_temp.CreateDataSet;   ClientDataSet1.Data := Ole_DataSet;
   try      
  //    frm_main.mainconn.BeginTrans;   //开始事务处理
      ClientDataSet1.First;
      while not ClientDataSet1.Eof do
      begin
         D_value := strTOFloat(ClientDataSet1.FieldValues['value']);
         S_Variable := ClientDataSet1.FieldValues['variable_name'];
         S_datetime := ClientDataSet1.FieldValues['date_time'];         try
           addflag := TFunc.addFlag(D_value,prg_name,S_Variable);
         except
           addflag := '' ;
         end;         ok_flag:=self.checkfields(prg_name,S_variable,floatTOstr(D_value));
         case ok_flag of
         0:
           begin
           end;
         1:   //合格数据
           begin
              saveInspData(S_datetime,floatTOstr(D_value),trim(computerName),trim(addflag));              cds_temp.Append;
              cds_temp.FieldByName('variable_name').AsString := S_Variable;
              cds_temp.FieldByName('value').AsString := floatTOstr(D_value);
              cds_temp.FieldByName('date_time').AsString := S_datetime;
              cds_temp.FieldByName('flag').AsBoolean :=true ;
              cds_temp.FieldByName('addflag').AsString := addflag;
              cds_temp.FieldByName('usl_value').AsString := floatTOstr(usl_value1);
              cds_temp.FieldByName('target_value').AsString := floatTOstr(target_value1);
              cds_temp.FieldByName('lsl_value').AsString := floatTOstr(lsl_value1);
              cds_temp.Post;
           end;
         2:   //不合格数据
           begin
              saveNoInspData(S_datetime,floatTOstr(D_value),trim(computerName),trim(addflag));              cds_temp.Append;
              cds_temp.FieldByName('variable_name').AsString := S_Variable;
              cds_temp.FieldByName('value').AsString := floatTOstr(D_value);
              cds_temp.FieldByName('date_time').AsString := S_datetime;
              cds_temp.FieldByName('flag').AsBoolean :=false ;
              cds_temp.FieldByName('addflag').AsString := addflag;
              cds_temp.FieldByName('usl_value').AsString := floatTOstr(usl_value1);
              cds_temp.FieldByName('target_value').AsString :=floatTOstr(target_value1);
              cds_temp.FieldByName('lsl_value').AsString := floatTOstr(lsl_value1);
              cds_temp.Post;
           end;
         end;
         ClientDataSet1.Next;
      end;
   //   frm_main.mainconn.CommitTrans; //提交事务
      ClientDataSet1.EmptyDataSet;
      result := cds_temp.Data;
   except
     on e:Exception do
     begin
     //   frm_main.mainconn.RollbackTrans;//当有错误时,回滚事务
        ClientDataSet1.EmptyDataSet;
        cds_temp.EmptyDataSet;
        frm_main.memo_System.Lines.Add(formatdatetime('yyyy-mm-dd hh:nn:ss      ',now)+e.Message);
     end;
   end;
 finally
    cds_temp.EmptyDataSet;
 end;
except
  on e:Exception do
  begin
     frm_main.memo_System.Lines.Add(formatdatetime('yyyy-mm-dd hh:nn:ss      ',now)+e.Message);
     cds_temp.EmptyDataSet;
  end;
end;
下面是Client上多线程中调用Server的一个函数部份代码:
           m_ah.ShowMsg('开始到服务器上检测variable 的完整性',1);
           try
              miss_String:=ClientDM.scktconn.AppServer.CheckAllAvriable(ClientDM.ClientDataSet3.Data,str_pro);  //调用服务器上的函数
           except
              on e:Exception do
                 m_ah.ShowMsg('到服务器上检查variable出错:'+e.Message);  
           end;
           m_ah.ShowMsg('完整性检查结束',1);
           if miss_String <> '' then
           begin
             tag1 := 'Miss Data';
             m_ah.ShowMsg('variabel不完整,缺少:'+miss_string+'开始打开缺少variable界面',1);
             pro_name := trim(str_pro);
             miss_tag := true;
            // SendMessage(frm_main.Handle,WM_USER + 2, 5, 0); //打开missForm窗口,线程不停止
           end
           else
           begin
             tag1 := 'NO Miss';
             pro_name := trim(str_pro);
             TRY
                m_ah.ShowMsg('开始到服务器上插入数据,',1);
                frm_main.cdsBase.Data := ClientDM.scktconn.AppServer.InsertAll(ClientDM.ClientDataSet3.Data,str_pro,computerName);//调用Server上的函数
                m_ah.ShowMsg('插入数据到服务器成功',1);
                frm_main.Edit1.Text := trim(str_pro);
             EXCEPT
                on e:exception do
                begin
                  m_ah.ShowMsg('插入数据到服务器上出错:'+e.Message);
                  frm_main.Edit1.Text := '';
                  frm_main.cdsBase.EmptyDataSet;
                end;
             end;
           end;
          end;
       end;   
请高手帮忙看看,到底哪里有问题了

解决方案 »

  1.   

    把sockconnection 的好像叫callback参数设为false 试试
      

  2.   

    6楼的说得对,有这种可能;还有,你在服务器程序中有没有Showmessage,如果有,必须去掉,否则,一旦showmessage,所有的客户端都会死机;
      

  3.   

    应该考虑升级到CBX RIA框架下,Delphi7的。中间层无状态,完全避免了死锁。
    讨论QQ群:16169282
      

  4.   

    可以试试使用GCI, 下载地址: http://download.csdn.net/source/255772