关于在目的URL繁忙或者网络异常的情况下,,TIdHTTP.Get(URL)没有任何信息反馈,一直阻塞在这里,导致整个线程停止,try...except也无法捕获异常,网络搜索这方的解决办法,但是一直找不到,ConnectTimeout或者ReadTimeout根本不起作用,哪位大侠有这方面的解决办法的???请出手相助,我出RMB也行,不过不要太多就可以了……

解决方案 »

  1.   

    try
      IdHTTP.Get(SUPAddress+'Supplier/ProductSaving.asp');   //网络正常的时候没有问题,要是网络慢的时候就一直卡在这里不动了
      Memo_Msg.Lines.Add(IntToStr(IdHTTP.ResponseCode));
    except
      //
    end;
      

  2.   

    我没使用IDNY的IdHTTP控件,网上有个单独的控件:HttpGet.
    我使用的这个控件没有你遇到这个问题,很好用的.
    你不妨下载一个试试看.
      

  3.   

    谢谢楼上的哥们,HttpGet不能满足其它方面的需求,idhttp有SSL的表单POST功能。我看HTTPGet好像主要用来断点下载的。
      

  4.   

    目前很多服务器放在机房的都在硬件防火墙的保护下的,但是经过测试,一般IDHTTP无响应都发生在网络较慢的时候的,所以说应该跟硬件防火墙的设置无关,而可能是发送的包丢失了无回应导致了IDHTTP一直阻塞。根本问题在于为何IDHTTP没有一个超时机制???有谁有解决办法的???
      

  5.   

    服务器一般情况下tcp连接超时时间为5分钟
      

  6.   

    只要是IDHTTP.GET卡住了就是无限时卡,一直卡着不动了。程序非常简单,不存在问题。try 
      IdHTTP.Get(SUPAddress+'Supplier/ProductSaving.asp');   //网络正常的时候没有问题,要是网络慢的时候就一直卡在这里不动了 
      Memo_Msg.Lines.Add(IntToStr(IdHTTP.ResponseCode)); 
    except 
      // 
    end;
      

  7.   

    IdHTTP是阻塞式的
    在indy misc里有个IdAntiFreeze,放上后可以改成非阻塞式
      

  8.   

    constructor ThttpObj.Create(Owner:TComponent);begin
      inherited create(Owner);
      IdAntiFreeze:=TIdAntiFreeze.Create(nil);
      OnWork:=IdHTTPWork;
      OnWorkBegin:=IdHTTPWorkBegin;
      OnWorkEnd:=IdHTTPWorkEnd;
      recvbuffersize:=32768;
      sendbuffersize:=32768;
      HandleRedirects:=true;
      Port:=80;
      Request.ContentType := 'application/x-www-form-urlencoded';
      HTTPOptions:=[];
      Request.Accept:= 'text/html, */*';
      Request.ContentLength:= 0;
      Request.ContentRangeEnd:= 0;
      Request.ContentRangeStart := 0;
      Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
    end;
    这里是我写的Create函数,好像没什么特别之处,但是我就是很奇怪,我用这段代码创建,就是没有碰到过你这种情况,而我直接用idhttp控件,确实也能碰到程序被挂死的情况,你把这段代码放到你的程序中试试看?
      

  9.   

    IdHttp不是由ConnectTimeout、ReadTimeout熟悉么?实在不行,用线程来解决问题,
      

  10.   

    谢谢各位大侠,我一直也是用线程操作的,线程中也是存在IDHTTP.GET挂死的现象导致线程无法继续运行,目前在测试yaxii的方法,如果OK了上来说一下,谢谢.
      

  11.   

    yaxii的代码里的IdAntiFreeze:=TIdAntiFreeze.Create(nil);等于就是放了个IdAntiFreeze.
    采用非阻塞式访问,当然不会使线程挂起了.直接用idhttp控件的时候配合放上一个IdAntiFreeze就可以了啊
      

  12.   

    在Form上面放一个IdAntiFreeze,对所有线程都有效么???我在线程里面动态创建,总是提示一个Application只允许有一个IdAntiFreeze,郁闷。
      

  13.   

    这个我没具体研究过,猜测一下:
    你在form上放一个IdAntiFreeze,然后在线程创建Tidhttp时候Tidhttp.create(form1) 
    应该就可以的吧
    实际上用了IdAntiFreeze,就没必要把idhttp放线程里面创建了.因为idhttp的工作方式本身仍然是阻塞式的,IdAntiFreeze的作用其实就是把你对idhttp的操作放到一个它创建的线程中去执行.
      

  14.   

    如果这样的话,那么IDHTTP发出请求候没有收到任何回应信息那么线程不就一直挂在那里地方不继续运行下面的代码了?
      

  15.   

    这个要研究下IdAntiFreeze的工作原理了.但我使用的时候都是正常的,所以我估计是IdAntiFreeze创建一个线程去执行你对IDHTTP的操作,这样不会影响你原有的线程
      

  16.   

    我线程里面的IDHTTP还结合了IdSSLIOHandlerSocket的,不知道是不是卡死了跟IdSSLIOHandlerSocket也有关。    IdSSLIOHandlerSocketOpenSSL:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
        IdSSLIOHandlerSocketOpenSSL.SSLOptions.Mode:=sslmClient;
        IdSSLIOHandlerSocketOpenSSL.SSLOptions.Method:=sslvTLSv1;
        IdSSLIOHandlerSocketOpenSSL.UseNagle:=false;
        IdSSLIOHandlerSocketOpenSSL.ConnectTimeout:=ReadTimeOut;
        IdSSLIOHandlerSocketOpenSSL.ReadTimeout:=ReadTimeOut;
      

  17.   

    看了下IdAntiFreeze和IdAntiFreezeBase两个单元.好像不是创建线程的.....大致看了下,好像是在超时之前一直是一个循环,但是在循环里面有Application.ProcessMessages;所以主程序的界面消息仍然可以得到响应有哪位大大深入研究过的来说说哈
      

  18.   

    不见可能的,我们就是用IdHTTP1来下载的,一开启程序的时候先检测服务器上有没有最新的版本,
    IdHTTP1 可以设置连接时间的,如果超过这个时间,他自动会返回1006,超时错误,
    没有一直卡在哪里,然后跳出下载.我们是在JAVA服务器端通信时,如果是调试的时候,
    在JAVA服务器端打上了断点的话,哪么是会停在哪里,一直等服务器响应,一般情况是不会的,很快就能返回端服端的信息
    到客户端.procedure HttpDownLoad(const aURL, aFile: string; bResume: Boolean);
    var
      tStream: TFileStream;
      IdHTTP1:TIdHTTP;
    begin  try
         //如果文件已经存在
        if FileExists(aFile) then
          tStream := TFileStream.Create(aFile, fmOpenWrite)
        else
          tStream := TFileStream.Create(aFile, fmCreate);    IdHTTP1:=TIdHTTP.Create(nil);
        if bResume then //续传方式
        begin
          IdHTTP1.Request.ContentRangeStart := tStream.Size - 1;
          tStream.Position := tStream.Size - 1; //移动到最后继续下载
          IdHTTP1.Head(aURL);
          IdHTTP1.Request.ContentRangeEnd := IdHTTP1.Response.ContentLength;
        end
        else //覆盖或新建方式
        begin
          IdHTTP1.Request.ContentRangeStart := 0;
        end;
        try
          IdHTTP1.Get(aURL, tStream); //开始下载
        finally
          tStream.Free;
        end;
      except
        on E: Exception do
        begin
          raise Exception.Create('下载文件'+aURL+'失败:'+e.Message);
        end;
      end;
    end;
      

  19.   

    问题就在这里了:在JAVA服务器端打上了断点的话,哪么是会停在哪里,一直等服务器响应,一般情况是不会的,很快就能返回端服端的信息 
    到客户端. 如果发送的请求包丢失又或者服务器没有返回数据包、返回的数据包丢失,那么就一直停在这里了。怎么处理这个问题???在网络繁忙、或者目的服务器负载比较重的情况下就发生了我碰到的现象了。求大侠们想想解决办法。
      

  20.   

    IDHTTP一套那么强大的组件,不应该考虑不到这些网络因素吧???
      

  21.   

    嗯,有这个问题的,详细见:http://i.92wy.com/html/96/756996-91916.html
      

  22.   

    以前写用它写抓取网页程序的时候,确实碰见过,百思不得其解,换控件解决的indy挺垃圾的
      

  23.   

    请问换什么控件可以代替indy?
      

  24.   

    自己写个SOCKET API client,自己设置ReadTimeout,保证没事,:D
      

  25.   

    可以使用多线程解决这个问题,把idhttp放到线程里动态创建,这样即使会卡死,也不会卡死主线程。实际上,卡死还是会发生,只不过在子线程里发生了。ConnectTimeout 在网络异常或服务器失去响应的情况下 不起作用的,因为 indy 是阻塞式通讯,没有返回就一直等待,直到超时,你可以看下这篇文章提到的方法:
    http://www.piaoyi.org/computer/Delphi-INDY-IDFTP-IDHTTP-connecttimeout.html彻底解决。
      

  26.   

    换成ICS !!
    Indy问题多!!!