IdTCPServer在OnExecute中传输文件;
IdTcpClient有一个接受文件事件;测试中传输的文件比较大,在传输的过程中我取消掉了(类似断线之类),TCPServer却一直还在发送,请问有Server如何来设置一个中断时间,超过这个时间就让连接断开(我知道在Client可以设置,即在IdTcpClient.OnWork事件中获取到传输时间);我发现IdTcpServer死掉后,其他客户端就不能连接了,这个后果很严重,请教各位朋友怎样才能消除这样的异常!附:系统Indy版本为10.2.3,另外添加了一个TIdSchedulerOfThreadPool线程池控件。

解决方案 »

  1.   

    IdTcpServer死掉,也只是那个发送文件内容的线程还在发送吧?
    别的线程应该不受影响啊
      

  2.   

    sz_haitao:  我也这样想的,理论上就应该像这样,但是发现服务器就是因为一个客户端而死掉了,与其他客户端也不能连接了。
      

  3.   

    socket方面的控件,很多细微还是控制不好
    不知道是用的问题,还是控件本身的问题
    所以,还是直接使用api的c/c++写服务程序更可控
      

  4.   

    “传输的文件比较大,”
    文件大的话最好用FTP
    如果用IdFtpServer 官方上有例子的
      

  5.   

    希望是我自己用的有问题,下面我大致讲述下我使用的方法
    【服务器】
    服务器端有IdTcpServer,IdSchedulerOfThreadPool和IdAntiFreeze,其中IdSchedulerOfThreadPool.MaxThreads设置为50
    程序:
    procedure TCPServerExecute(AContext: TIdContext);
    var
      RcvStr: String;
      AFileStream: TFileStream;
    begin
      try
        try
          if (AContext.Connection.Connected) then
          begin
            RcvStr := AContext.Connection.IOHandler.ReadLn;
            AFileName := ExtractFilePath(ParamStr(0)) + 'test.exe';
            if SameText(RcvStr, 'File-') and FileExists(AFileName) then
            begin
              AFileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
              try
                AContext.Connection.IOHandler.WriteLn(IntToStr(AFileStream.Size));
                RcvStr := AContext.Connection.IOHandler.ReadLn;
                if SameText(RcvStr, '-Ready') then
                begin
                  AContext.Connection.IOHandler.LargeStream := True;
                  AContext.Connection.IOHandler.Write(AFileStream, AFileStream.Size);
                end;
                if AContext.Connection.IOHandler.InputBuffer.Size >0 then
                  AContext.Connection.IOHandler.InputBuffer.Clear;
              finally
                FreeAndNil(AFileStream);
              end;
            end;
        except
          //
        end;
      finally
        if AContext.Connection.Connected then
        begin
          AContext.Connection.IOHandler.CloseGracefully;
          AContext.Connection.Disconnect;
        end;
        LeaveCriticalSection(_TSection);
      end;
    end;【客户端】
    客户端有一个IdTcpClient,IdAntiFreeze
    程序:
    function TFrmMain.DownloadFile: Boolean;
    var
      SendStr, RcvStr: String;
      Size: Int64;
      AFileName: String;
      AFileStream: TFileStream;
    begin
      Result := True;
      try
        try
          TCPClient.Host := '127.0.0.1';
          TCPClient.Port := 6000;
          if not TCPClient.Connected then
            TCPClient.Connect;      SendStr := 'File-';
          TCPClient.IOHandler.WriteLn(SendStr);
          RcvStr := TCPClient.IOHandler.ReadLn;
          Size := StrToInt64Def(RcvStr, 0);
          if Size >0 then
          begin
            TCPClient.IOHandler.WriteLn('-Ready');
            AFileName := 'd:\test.exe';
            AFileStream := TFileStream.Create(AFileName, fmCreate);
            try
              TCPClient.IOHandler.LargeStream := True;
              TCPClient.IOHandler.ReadStream(AFileStream, Size);
            finally
              FreeAndNil(AFileStream);
            end;
          end;      if TCPClient.IOHandler.InputBuffer.Size >0 then
            TCPClient.IOHandler.InputBuffer.Clear;
        except
          on E: Exception do
          begin
            Result := False;
          end;
        end;
      finally
        if TCPClient.Connected then
        begin
          TCPClient.IOHandler.CloseGracefully;
          TCPClient.Disconnect;
        end;
      end;
    end;
      

  6.   

    现在CSDN怎么提前?找了半天都没有了。真晕菜了。
    顶一下,别沉下去!
      

  7.   

    知道原因了,去掉_TSection,没有多思考下,呵呵。
    结贴了。