procedure TPrm_Proxy.IdTCPServerExecute(AThread: TIdPeerThread);
     
Var
StrRe:String;
  StrDtlInfo:String;
  RcvStrStream:TStringStream;   
begin
if   not   AThread.Terminated   and   AThread.Connection.Connected   then     //注意这里
    begin
StrRe:=AThread.Connection.ReadLn();
        {if SameText(StrRe,'') then
         Exit;  }
     MemoDealInfo.Lines.Add('--->'+DateTimeToStr(Now)+':收到来自客户端'+ AThread.Connection.Socket.Binding.PeerIP+':'+inttoStr(AThread.Connection.Socket.Binding.PeerPort)+'的请求信息:'+StrRe);
     //StrDtlInfo:=;
     RcvStrStream:= TStringStream.Create(IdHTTP.Get(StrRe));//IdHTTP.Get('http://172.18.14.150:9080/proxychmp/detail/detailgprs.jsp?devno=13301316227&startday=20090301&endday=20090331&lang=cn')
        RcvStrStream.Position:=0;
     StreamM.LoadFromStream(RcvStrStream);
        //StreamM.Position:=0;
        //Memo1.Lines.LoadFromStream(RcvStrStream);
     //ShowMessage(StrRe)  ;        try
            //RcvStrStream.Position:=0;
     AThread.Connection.WriteStream(RcvStrStream,true,true);
     MemoDealInfo.Lines.Add('<---'+DateTimeToStr(Now)+':已回应客户端'+AThread.Connection.Name+'的请求信息:');    //+StrDtlInfo
        except
            AThread.Connection.WriteLn('SvcFailed');
     RcvStrStream.Free;
     //StreamM.Free;
            //Athread.Connection.ClearWriteBuffer;//2009.4.16
           Athread.Connection.DisconnectSocket;
         AThread.Connection.Disconnect;
            Exit;
        end;
        //AThread       .Connection.WriteLn('SvcSuccess');
     RcvStrStream.Free;
        Athread.Connection.DisconnectSocket;         AThread.Connection.Disconnect;
    end;  
end;单个连接的时候没有问题。多个客户端连接的时候,就乱了,比如张三的请求返回给李四了,李四的返回给王五了。各位大侠快伸出你的援手,谢谢!

解决方案 »

  1.   

    写个线程,当有用户连接的时候把AThread传递到线程里面进行处理,这个AThread就是双方的连接链路
      

  2.   

    hongqi162有程序不?>_<有的话,发来看看。因为程序已经投入使用了,现在突然出问题,必须尽快解决才行。IdTCPServer在网上可借鉴的源码不是很多,估计现在用
    IdTCPServer的人也不多了。
      

  3.   

    在TIdTCPServer的OnExecute事件代码不是线程安全的, 不要直接操作可视化的VCL组件, 比如 MemoDealInfo.Lines.Add......, ShowMessage(......)这类的语句, 否则会导致不可预测的错误。AThread已经是唯一对应某个客户端的, 通过AThread.Connection.Write...这类语句, 是不会"张三的请求返回给李四"的。
      

  4.   

    嗯,那我我去掉memo这块试试。希望是这个原因。请大家继续帮我看看还有没有其他的问题,谢谢
      

  5.   

    Channels_net,请问在哪里加?现在程序改成这样了
    procedure TPrm_Proxy.IdTCPServerExecute(AThread: TIdPeerThread);
       
    Var
      StrRe:String;
      StrDtlInfo:String;
      RcvStrStream:TStringStream; 
    begin
        if  not  AThread.Terminated  and  AThread.Connection.Connected  then    //注意这里
        begin
         StrRe:=AThread.Connection.ReadLn();     RcvStrStream:= TStringStream.Create(IdHTTP.Get(StrRe));//IdHTTP.Get('http://172.18.14.150:9080/proxychmp/detail/detailgprs.jsp?devno=13301316227&startday=20090301&endday=20090331&lang=cn')
         RcvStrStream.Position:=0;
         StreamM.LoadFromStream(RcvStrStream);
         try
         AThread.Connection.WriteStream(RcvStrStream,true,true);
         except
             AThread.Connection.WriteLn('SvcFailed');
         RcvStrStream.Free;
             AThread.Connection.Disconnect;
             Exit;
         end;     RcvStrStream.Free;
         AThread.Connection.Disconnect;
        end; 
    end; 
      

  6.   

    缩进还是乱了
    procedure TPrm_Proxy.IdTCPServerExecute(AThread: TIdPeerThread);
       
    Var
      StrRe:String;
      StrDtlInfo:String;
      RcvStrStream:TStringStream; 
    begin
        if  not  AThread.Terminated  and  AThread.Connection.Connected  then    //注意这里
        begin
         StrRe:=AThread.Connection.ReadLn();     RcvStrStream:= TStringStream.Create(IdHTTP.Get(StrRe));
         RcvStrStream.Position:=0;
         StreamM.LoadFromStream(RcvStrStream);
         try
         AThread.Connection.WriteStream(RcvStrStream,true,true);
         except
             AThread.Connection.WriteLn('SvcFailed');
         RcvStrStream.Free;
             AThread.Connection.Disconnect;
             Exit;
         end;     RcvStrStream.Free;
         AThread.Connection.Disconnect;
        end; 
    end; 
      

  7.   

    去掉memo显示也不行,还是会出现乱回应的现象
      

  8.   

    每个客户端连接,服务器都会创建一个TIdPeerThread,绝对不会乱IdTcpServer的例子非常多,indy demo里就有2个
      

  9.   

    加了临界区,还是有作用的,数据不会错传了。可是现在又出现新问题了,多个客户端同时访问,过一段时间,程序就会死掉。我真后悔当初怎么用了这个破组件,欲哭无泪啊。现在的代码如下:
        EnterCriticalSection(MyCs_2); //进入临界区 //临界变量     zxh debug 2009.6.2
    if   not   AThread.Terminated   and   AThread.Connection.Connected   then     //注意这里
        begin StrRe:=AThread.Connection.ReadLn();
            //拆分客户端传来的(日志、Tuxedo请求)信息A|B|C
            SplitString(StrArrRe,StrRe,'|');
            //拆分客户端传来的(日志、Tuxedo请求)信息A|B|C
            SplitString(StrArrRe,StrRe,'|');        //查看是tuxedo服务请求还是日志存储请求
            if(SameText(StrArrRe[0],'Log')) then
            begin
         //MemoDealInfo.Lines.Add('--->'+DateTimeToStr(Now)+':收到来自客户端'+ AThread.Connection.Socket.Binding.PeerIP+':'+inttoStr(AThread.Connection.Socket.Binding.PeerPort)+'的请求信息:'+StrRe);  //zxh debug 2009.6.2         //IdTCPClient_DB.WriteLn(StrMobileNumber+'|'+inttostr(Dtl_Type)+'|'+StrPkg);
             try
             //DataModule_t.SaveLogInfo(StrArrRe[1],StrToInt(StrArrRe[2]),StrArrRe[3]);   zxh debug 2009.6.3
         //MemoDealInfo.Lines.Add('<---'+DateTimeToStr(Now)+':已存储日志信息:'+StrRe);   //zxh debug 2009.6.2
             finally
             //AThread.Connection.WriteLn('DBFailed');
               Athread.Connection.DisconnectSocket; //zxh debug 2009.6.2
             AThread.Connection.Disconnect;
                    Athread.Terminate;        //2009.6.3
                    //Athread.Free;                    //2009.6.3
             LeaveCriticalSection(MyCs_2); //离开临界区  zxh debug 2009.6.2         end;
         end //if log
            else if(SameText(StrArrRe[0],'Tuxedo')) then
            begin
             StrMobileNumber:=StrArrRe[1];
                StrPwd:=StrArrRe[2];            IntRe:=-9999;
                IntRe:=User_Auth(pChar(StrMobileNumber),pChar(StrPwd));
                try             AThread.Connection.WriteLn(intToStr(IntRe));
             finally
             //AThread.Connection.WriteLn('DBFailed');
               Athread.Connection.DisconnectSocket; //zxh debug 2009.6.2
             AThread.Connection.Disconnect;
                    Athread.Terminate;        //2009.6.3
                    //Athread.Free;                    //2009.6.3
             LeaveCriticalSection(MyCs_2); //离开临界区  zxh debug 2009.6.2         end;
            end //if tuxedo
            else //HTTP请求
            begin
         //MemoDealInfo.Lines.Add('--->'+DateTimeToStr(Now)+':收到来自客户端'+ AThread.Connection.Socket.Binding.PeerIP+':'+inttoStr(AThread.Connection.Socket.Binding.PeerPort)+'的请求信息:'+StrRe); //zxh debug 2009.6.2
         //StrDtlInfo:=;
         RcvStrStream:= TStringStream.Create(IdHTTP.Get(StrRe));//IdHTTP.Get('http://172.18.14.150:9080/proxychmp/detail/detailgprs.jsp?devno=13301316227&startday=20090301&endday=20090331&lang=cn')
             RcvStrStream.Position:=0;
         StreamM.LoadFromStream(RcvStrStream);         try
                 //RcvStrStream.Position:=0;
         AThread.Connection.WriteStream(RcvStrStream,true,true);
         //MemoDealInfo.Lines.Add('<---'+DateTimeToStr(Now)+':已回应客户端'+AThread.Connection.Name+'的请求信息:');    //+StrDtlInfo zxh debug 2009.6.2
             finally
                 //AThread.Connection.WriteLn('SvcFailed');         //AThread.Connection.WriteLn('DBFailed');
               Athread.Connection.DisconnectSocket; //zxh debug 2009.6.2
             AThread.Connection.Disconnect;
                    Athread.Terminate;        //2009.6.3
                    //Athread.Free;                    //2009.6.3
             LeaveCriticalSection(MyCs_2); //离开临界区  zxh debug 2009.6.2         end;
            end;//HTTP请求
        end;// not   AThread.Terminated
      

  10.   

    把注释去掉,看起来太费劲了
    INDY组件虽然BUG比较多,但是还是不错的
      

  11.   

    IdHTTP.Get(StrRe)
    你的问题应该出在这里,请用一个其他的字符串代替了试试
      

  12.   

    EnterCriticalSection(MyCs_2); //进入临界区 //临界变量    zxh debug 2009.6.2
    if  not  AThread.Terminated  and  AThread.Connection.Connected  then    //注意这里
         begin StrRe:=AThread.Connection.ReadLn();         //拆分客户端传来的(日志、Tuxedo请求)信息A|B|C
             SplitString(StrArrRe,StrRe,'|');         //查看是tuxedo服务请求还是日志存储请求
             if(SameText(StrArrRe[0],'Log')) then
             begin         
             try
             finally
            
               Athread.Connection.DisconnectSocket; //zxh debug 2009.6.2
             AThread.Connection.Disconnect;
                     Athread.Terminate;        //2009.6.3                
             LeaveCriticalSection(MyCs_2); //离开临界区  zxh debug 2009.6.2
             end;
         end //if log
            else if(SameText(StrArrRe[0],'Tuxedo')) then
            begin
             StrMobileNumber:=StrArrRe[1];
                 StrPwd:=StrArrRe[2];             IntRe:=-9999;
                 IntRe:=User_Auth(pChar(StrMobileNumber),pChar(StrPwd));
                 try             AThread.Connection.WriteLn(intToStr(IntRe));
             finally        
               Athread.Connection.DisconnectSocket; //zxh debug 2009.6.2
             AThread.Connection.Disconnect;
                     Athread.Terminate;        //2009.6.3
                    
             LeaveCriticalSection(MyCs_2); //离开临界区  zxh debug 2009.6.2         end;
            end //if tuxedo
            else //HTTP请求
            begin     RcvStrStream:= TStringStream.Create(IdHTTP.Get(StrRe));//IdHTTP.Get('http://172.18.14.150:9080/proxychmp/detail/detailgprs.jsp?devno=13301316227&startday=20090301&endday=20090331&lang=cn')
             RcvStrStream.Position:=0;
         StreamM.LoadFromStream(RcvStrStream);
             try
         AThread.Connection.WriteStream(RcvStrStream,true,true);
        
             finally 
               Athread.Connection.DisconnectSocket; //zxh debug 2009.6.2
             AThread.Connection.Disconnect;
                     Athread.Terminate;        //2009.6.3
                    
             LeaveCriticalSection(MyCs_2); //离开临界区  zxh debug 2009.6.2
             end;
            end;//HTTP请求
        end;// not  AThread.Terminated
      

  13.   

    先从客户端收请求信息,然后判断是“登录请求”、“日志存储请求”还是“查询信息请求”如果是“登录请求”,就去验证用户身份“User_Auth(pChar(StrMobileNumber),pChar(StrPwd))”,并将验证结果发送给客户端。如果是“日志存储”,就去操作数据库存储日志(因为怀疑是操作数据库导致的,所以这段代码被我去掉了)如果是“查询信息”请求,就去IdHTTP.Get信息,并返回给客户端。回shuihan20e,没加临界区,一直出现错传的现象....加了就没了。
      

  14.   

    procedure TPrm_Proxy.IdTCPServer_DB_TuxedoExecute(AThread: TIdPeerThread);
    Var
        StrRe:String;
        StrArrRe:Array [0..19] of String;
        StrMobileNumber,StrPwd:String;
        Stra,Strb,Strc,Strd:pChar;
        IntRe:integer;
        i:integer;
        Handle:   THandle;
        Auth:   TMyApp;
        a,b:integer;
        RcvStrStream:TStringStream;  
    begin
        EnterCriticalSection(MyCs_2); //进入临界区 //临界变量     zxh debug 2009.6.2
        if   not   AThread.Terminated   and   AThread.Connection.Connected   then     //注意这里
        begin
            StrRe:=AThread.Connection.ReadLn();
            //拆分客户端传来的(日志、Tuxedo请求)信息A|B|C
            SplitString(StrArrRe,StrRe,'|');        //查看是tuxedo服务请求还是日志存储请求
            if(SameText(StrArrRe[0],'Log')) then
            begin
                try
                    DataModule_t.SaveLogInfo(StrArrRe[1],StrToInt(StrArrRe[2]),StrArrRe[3]);   zxh debug 2009.6.3
                finally
                    Athread.Connection.DisconnectSocket; //zxh debug 2009.6.2
                    AThread.Connection.Disconnect;
                    LeaveCriticalSection(MyCs_2); //离开临界区  zxh debug 2009.6.2
                end;
            end //if log
            else if(SameText(StrArrRe[0],'Tuxedo')) then
            begin
                StrMobileNumber:=StrArrRe[1];
                StrPwd:=StrArrRe[2];            IntRe:=-9999;
                IntRe:=User_Auth(pChar(StrMobileNumber),pChar(StrPwd));
                try
                    AThread.Connection.WriteLn(intToStr(IntRe));
                finally
                    Athread.Connection.DisconnectSocket; //zxh debug 2009.6.2
                    AThread.Connection.Disconnect;
                    leaveCriticalSection(MyCs_2); //离开临界区  zxh debug 2009.6.2            end;
            end //if tuxedo
            else //HTTP请求
            begin    
                RcvStrStream:= TStringStream.Create(IdHTTP.Get(StrRe));
                RcvStrStream.Position:=0;
                StreamM.LoadFromStream(RcvStrStream);
                try
                    AThread.Connection.WriteStream(RcvStrStream,true,true);
                finally
                    Athread.Connection.DisconnectSocket; //zxh debug 2009.6.2
                    AThread.Connection.Disconnect;
                    LeaveCriticalSection(MyCs_2); //离开临界区  zxh debug 2009.6.2
                end;
            end;//HTTP请求
        end;// not   AThread.Terminated
      

  15.   

    procedure TPrm_Proxy.IdTCPServer_DB_TuxedoConnect(AThread: TIdPeerThread);
    begin
        AThread.FreeOnTerminate:=true;
    end;procedure TPrm_Proxy.IdTCPServer_DB_TuxedoException(AThread: TIdPeerThread;
      AException: Exception);
    begin
        MemoDealInfo.Lines.Add('DB代理出现异常:'+AException.Message);
        AThread.Data:=nil;    if AThread.Connection.Connected then
            AThread.Connection.DisconnectSocket;
        try
            AThread.Destroy;
            AThread:=nil;
        except
        end;   
    end;procedure TPrm_Proxy.FormDestroy(Sender: TObject);
    var
        List: TList;
        I: Integer;
    begin
        List := IdTCPServer_DB_Tuxedo.Threads.LockList;
        try
            Application.ProcessMessages;
            for I := 0 to List.Count - 1 do
            begin
                try
                    TIdPeerThread(List.Items[I]).Connection.DisconnectSocket;
                except
                    on E: Exception do
                    begin
                        TIdPeerThread(List.Items[I]).Stop;
                    end;
                end; //ex
    end;  //for
        finally //fina
            IdTCPServer_DB_Tuxedo.Threads.UnlockList;
        end;    DeleteCriticalSection(MyCs_2); //临界变量     zxh debug 2009.6.2
    end;procedure TPrm_Proxy.FormCreate(Sender: TObject);
    begin
        InitializeCriticalSection(MyCs_2);   //临界变量     zxh debug 2009.6.2
    end;上面是所有的处理代码