程序在这种情况下CPU占100% , 请教这如何解决 ,谢谢!

解决方案 »

  1.   

    InternetReadFile就算占CPU也不可能这么夸张,应该是有死循环吧!!
      

  2.   

    这个函数可以用来下载文件或者读取网页源码使用。有办法避免你所说的问题。
    建议在使用该函数前先调用HttpQueryInfo取得头信息来决定网页是否能正常响应,于是你的问题解决。如果你是个懒人,希望我直接给你贴出代码。那么请你再加100分后并结贴给分,并说清楚你是取文件还是取网页源码。我给你贴出实现代码。
      

  3.   


    我是有获取两个网站的源码的,一个没问题,另一个就是卡在 InternetReadFile函数里(可能是这个网站服务器无反应,在网上查的)
      

  4.   

    那是你的错误认为而已。取源码的方式很多,但用InternetOpen和InternetReadFile确实是最稳定的方法,而且纯代码实现不依靠外部控件。我所采用的就是你所说的方法。你所遇到的问题我在两年前就遇到过。所以有针对性的在回你的贴子。这里说一下,delphi7在同时使用InternetOpen,InternetOpenURL,InternetCloseHandle,InternetReadFile四个函数时会被360杀毒软件报毒。另外InternetReadFile应该写在循环里多次读取,因为有些源码过多,一次性无法读完整。http://www.mwymwy.com/GetURLCode.rar
    这里给出一个dcu测试版本,完全解决你的问题,不会出现断开或无法响应而导致无法返回的问题。你可以像源码一样移植到其它程序中使用和编译,但并不是源码。源码需要你加分后才公开。
      

  5.   


    先谢谢你先,是这样的,我之前在请求头里没有加上Accept-Encoding: gzip, deflate,我猜测服务器以
    此识别客户是不是IE方式读数据,因此在段时间后就被踢出来了,现在加上后就没有这种情况了,但现在又
    多了一个新的问题,就是GZIP解压缩的问题,我用的是ZLIP,但总是报DATA ERROR的错误,不知这位朋友
    有没有遇到这种情况,望赐教,还有我这个贴真的是加不了分了,我的QQ 814207582 可以加,希望继续交
    流下去,谢谢了
      

  6.   

    我也用的是ZLIP,没用过GZI,所以你的后续问题我解决不了。抱歉。
      

  7.   


    现在发现是获取源码哪里出错了,我用IDHTTP获取的可以解压,但用internetreadfile获取的解压就出错,不知道是什么原因,我现在把源码贴出来吧function HttpGetString(mUrl , mReferer: string ; var mStringResult : string; mMethod : string;bGzip : boolean) : boolean;
    var
      hSession, hConnect, hRequest: hInternet;
      HostName, FileName, mData: String;
      f: File;
      Buf: Pointer;
      dwBufLen, dwIndex: DWord;
      Data: Array[0..1024] of Char;//Array[0..$400] of Char;
      TempStr: String;
      RequestMethod: PChar;
      InternetFlag: DWord;
      AcceptType: LPStr;
      mResult : boolean;
      mFileSize : integer;
      mBinaryData : boolean;
      BytesToRead, BytesReaded: DWord;
      p : integer;  procedure ParseURL(URL: String; var HostName, FileName: String); //取得精确的服务器名字,和地址文件
      //HTTP://<IP 地址>/[端口号]/[路径][?<查询信息>]
      procedure ReplaceChar(c1, c2: Char; var St: String);
      var
      p : Integer;
      begin
      while True do
      begin
      p := Pos(c1, St);
      if p = 0 then
      break
      else
      St[p] := c2;
      end;
      end;  var
      i : Integer;
      begin
      if Pos('http://', LowerCase(URL)) <> 0 then
      System.Delete(URL, 1, 7);
      i := Pos('/', URL);
      HostName := Copy(URL, 1, i);
      FileName := Copy(URL, i, Length(URL) - i + 1);  if (Length(HostName) > 0) and (HostName[Length(HostName)] = '/') then
      SetLength(HostName, Length(HostName) - 1);
      end;  procedure CloseHandles; //5, 最后依次关闭request,connect,session句柄
      begin  
      InternetCloseHandle(hRequest);
      InternetCloseHandle(hConnect);
      InternetCloseHandle(hSession);
      end;  begin
      try
      ParseURL(mUrl, HostName, FileName);
      //showmessage(HostName + ' ' + FileName);
      hSession := InternetOpen(PChar('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET4.0C)'), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
      hConnect := InternetConnect(hSession, PChar(HostName), INTERNET_DEFAULT_HTTP_PORT, PChar(''), PChar(''), INTERNET_SERVICE_HTTP, 0, 0);
      RequestMethod := PChar(mMethod);//('GET'); //
      InternetFlag := INTERNET_FLAG_RELOAD;//0; //是否取用缓存 InternetFlag := INTERNET_FLAG_RELOAD;
      AcceptType := PChar('*/*'); //接受类型
      //3, 然后我们使用这个connect句柄来打开Http 请求得到一个HINTERNET request句柄;
      hRequest := HttpOpenRequest(hConnect, //通过InternetConnect()函数调用返回的HINTERNET类型的句柄
      RequestMethod, //该参数是一个指向包含请求所使用的动词的字符串,如果为NULL,那么表示的是GET请求,可以选择有:
      //GET:接收服务器发送的数据
      //POST:向服务器发送执行的操作
      //HEAD:接收服务器对请求的响应标题
      //DELETE:删除服务器上的一个资源
      //PUT:为服务器发送存储信息
      //LINK:在URL之间建立连接
      PChar(FileName), //表示操作的对象,一般情况下为一个要接收的文件的文件名
      'HTTP/1.1', //表示所使用的HTTP协议版本。NULL值表示HTTP/1.0
      PChar(mReferer), //表示页的URL,lpszObjectName指定的信息存放在这个地址中
      @AcceptType, //指定客户端可接受的信息类型。NULL则视为接收“text/*”类型,即文本类型
      InternetFlag, //给出调用该函数的其他选项
      0); //为异步I/O设置环境
      //HttpAddRequestHeaders(hRequest, 'Accept-Language: zh-cn',length('Accept-Language: zh-cn'), HTTP_ADDREQ_FLAG_ADD or HTTP_ADDREQ_FLAG_REPLACE);
      HttpAddRequestHeaders(hRequest, 'Connection: Keep-Alive',length('Connection: Keep-Alive'), HTTP_ADDREQ_FLAG_ADD or HTTP_ADDREQ_FLAG_REPLACE);
      //HttpAddRequestHeaders(hRequest, 'Content-Type: application/x-www-form-urlencoded;charset=utf-8',length('Content-Type: application/x-www-form-urlencoded;charset=utf-8'), HTTP_ADDREQ_FLAG_ADD or HTTP_ADDREQ_FLAG_REPLACE);
      if bGZip = True then
      HttpAddRequestHeaders(hRequest, 'Accept-Encoding: gzip, deflate',length('Accept-Encoding: gzip, deflate'), HTTP_ADDREQ_FLAG_ADD or HTTP_ADDREQ_FLAG_REPLACE);
      HttpAddRequestHeaders(hRequest, 'x-requested-with: XMLHttpRequest',length('x-requested-with: XMLHttpRequest'), HTTP_ADDREQ_FLAG_ADD or HTTP_ADDREQ_FLAG_REPLACE);
      //Content-Type
      //4, 这时我们就可以使用这个request句柄来发送数据与读取从服务器返回的数据;//gzip, deflate
      HttpSendRequest(hRequest, //是HttpOpenRequest()函数调用返回的句柄
      nil, //此参数用来指定发送时附加的头,这个标题和请求一起被发送
      0, //标题的长度
      nil, //指向待发送的数据
      0); //待发送数据的长度  dwIndex := 0;
      dwBufLen := 1024;
      GetMem(Buf, dwBufLen);
      //获取服务器对请求的响应信息
      mResult := HttpQueryInfo(hRequest, //是HttpOpenRequest()函数调用返回的句柄
      HTTP_QUERY_RAW_HEADERS_CRLF,//HTTP_QUERY_CONTENT_LENGTH, //指定返回信息及返回的方式 (返回文件的大小)
      Buf, //存放返回信息(指针)
      dwBufLen, //返回信息的长度
      dwIndex); //存放下一个匹配的标题索引值,如果找不到匹配的标题,那么此值将返回:ERROR_HTTP_HEADER_NOT_FOUND
      Form1.Memo3.Lines.Add(PChar(Buf));
      mData := PChar(Buf);
      p := pos('X-Last-Serial:',mData);
      if p <> 0 then
      begin
      system.Delete(mData,1,p+length('X-Last-Serial:')-1);
      pos('Content-Type:',mData);
      mData := Trim(copy(mData,1,pos('Content-Type:',mData)-1));
      s_A_SerialID := mData;
      end;
      mResult := HttpQueryInfo(hRequest, //是HttpOpenRequest()函数调用返回的句柄
      HTTP_QUERY_CONTENT_LENGTH, //指定返回信息及返回的方式 (返回文件的大小)
      Buf, //存放返回信息(指针)
      dwBufLen, //返回信息的长度
      dwIndex);
      mBinaryData := false;
      if mResult or not mBinaryData then
      begin
      //mFileSize := StrToInt(StrPas(Buf)); //把文件长度付给FTFileSize 无用?
      BytesReaded := 0;
      mStringResult := '';
      //Form1.Memo3.Lines.Add('********************');
      while True do //死循环,不断读取网络文件数据
      begin
      BytesToRead := 1024;
      //Form1.Memo3.Lines.Add('********ReadFile********');
      if not InternetReadFile(hRequest,@Data,1024,BytesToRead) then
      begin
      mResult := False;
      Break; //如果网络读取字节流不成功,则退出循环
      end
      else
      begin
      //Form1.Memo3.Lines.Add('********EndFile********');
      if BytesToRead = 0 then
      begin
      mResult := False;
      Break; //如果读取数据为0,则跳出循环
      end
      else
      begin
      TempStr := Data;
      SetLength(TempStr,BytesToRead);
      mStringResult := mStringResult + TempStr;
      inc(BytesReaded,BytesToRead); //保存已经读取的总字节数
      //Form1.Memo3.Lines.Add(FloatToStr(BytesToRead)+' '+FloatToStr(BytesReaded));
      end;
      end;
      end;
      SetLength(mStringResult, BytesReaded); //设置变量FTStringResult大小,
      mResult := BytesReaded <> 0; //保存结果
      end;
      //Form1.Memo3.Lines.Add('********END********');
      Result := mResult;
      FreeMem(Buf); //释放内存
      CloseHandles;
      except
      mResult := false;
      Result := mResult;
      //Form1.Memo3.Lines.Add(mUrl + '出错了');
      end;  
    end
      

  8.   

    可能是你的internetreadfile没把文件读完整,或漏掉几个字节。导致的问题。