我用idftp做上传的时候发现程序过一段时间就会死掉,调试发现程序在下面这个while中陷入死循环
function TIdSimpleServer.Listen: Boolean;
begin
  //TODO: Add a timeout to this function.
  Result := False;
  if not FListening then begin
    BeginListen;
  end;
  with Binding do begin
    if FAbortedRequested = False then
    begin
      while (FAbortedRequested = False) and (Result = False) do begin
        Result := Readable(AcceptWait);
      end;
    end;
    if Result then begin
      Binding.Listen(1);
      Binding.Accept(binding.Handle);
    end;
    GStack.WSCloseSocket(ListenHandle);
    FListenHandle := Id_INVALID_SOCKET;
  end;
end;
就是
while (FAbortedRequested = False) and (Result = False) do begin Result := ReadableAcceptWait);这句跳不出去
请教各位高手可能是什么原因造成的,有什么方法解决?多谢

解决方案 »

  1.   

    FAbortedRequested 退出请求。 FAbortedRequested = False 没有退出请求。因为 idFtp 工作阻塞模式,所以网络状况不好的情况下,不能接受到 Abort 命令。Result Listen 监听啊。Result = False 不监听。(FAbortedRequested = False) and (Result = False)
    没有退出请求 and 不监听解决方法不知道,没见过。
      

  2.   

    感谢楼上的帮助,那么我想接着问:result的结果是根据什么得到的,什么情况下会一直是false呢?
    我感觉我这里的网络状况还是不错的
      

  3.   

    //TODO: Add a timeout to this function.
      Result := False;1,开始的时候你就对她付了 False ,保证能进行循环。这个跟操作系统里,设计的很多东西一样。2,while (FAbortedRequested = False) and (Result = False) do begin
            Result := Readable(AcceptWait);
          end;循环里面可以将 Result 变为 True, 说明监听事件完成。Readable(AcceptWait); 返回以只读方式的 为 True 。
    有可能能读这个文件了,就不要监听了。我想你的流程,你自己更清楚。
      

  4.   

    非常感谢yeeyee(易 一 在追 M*M) ,不过这是idftp的东西,我只是拿他做了一个简单的上传测试程序,也就是每个5秒向服务器上传一个文件,就出现了这个问题,还真不清楚具体怎么的执行的
    还有下面那句Result := Select(0, @FDRead, @FDWrite, @FDError, @tmTO);为什么调试的时候进不去select函数?
    function TIdStackWindows.WSSelect(ARead, AWrite, AErrors: TList; ATimeout: Integer): Integer;
    var
      tmTo: TTimeVal;
      FDRead, FDWrite, FDError: TFDSet;  procedure GetFDSet(AList: TList; var ASet: TFDSet);
      var
        i: Integer;
      begin
        if assigned( AList ) then begin
          AList.Clear; // SG 18/10/00: ALWAYS clear the result list
          AList.Capacity := ASet.fd_count;
          for i := 0 to ASet.fd_count - 1 do begin
            AList.Add(TObject(ASet.fd_array[i]));
          end;
        end;
      end;  procedure SetFDSet(AList: TList; var ASet: TFDSet);
      var
        i: integer;
      begin
        if AList <> nil then begin
          if AList.Count > FD_SETSIZE then begin
            raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded);
          end;
          for i := 0 to AList.Count - 1 do begin
            ASet.fd_array[i] := TIdStackSocketHandle(AList[i]);
          end;
          ASet.fd_count := AList.Count;
        end;
      end;begin
      FillChar(FDRead, SizeOf(FDRead), 0);
      FillChar(FDWrite, SizeOf(FDWrite), 0);
      FillChar(FDError, SizeOf(FDError), 0);
      SetFDSet(ARead, FDRead);
      SetFDSet(AWrite, FDWrite);
      SetFDSet(AErrors, FDError);
      if ATimeout = IdTimeoutInfinite then begin
        Result := Select(0, @FDRead, @FDWrite, @FDError, nil);
      end else begin
        tmTo.tv_sec := ATimeout div 1000;
        tmTo.tv_usec := (ATimeout mod 1000) * 1000;
        Result := Select(0, @FDRead, @FDWrite, @FDError, @tmTO);
      end;
      GetFDSet(ARead, FDRead);
      GetFDSet(AWrite, FDWrite);
      GetFDSet(AErrors, FDError);
    end;
      

  5.   

    上面的代码不想分析。你可以到网站上下载,IdFTP 的 Demo (实例)看下。www.2ccc.com  www.playicq.com 上面都有,飞思科技的  《Delphi 网络应用开发》都有 Demo(实例) 。我的代码不可能给你,公司的商业行为。