如题
小弟有个项目需要用到上述的功能,因为客户端与服务器之间使用ADSL连接,网络带宽只有512K,所以会很慢,每次传输的数据量大约为30M的文本文件,需要查看进度。
不想用FTP之类
谢谢大家

解决方案 »

  1.   

    修改socketconnect控件就可以了,找到TSocketTransport的reveive函数,在里面加个自定义的事件调用就可以了
      

  2.   

    就是显示进度?前面我可能说的不清楚简单办法就是改控件,在unit SConnect;中定义一个事件,如下:
     
    TOnReceiveData = procedure (sender : Tobject;const MaxLen,CurLen : Integer) of object;首先改TSocketTransportTSocketTransport = class(TInterfacedObject, ITransport);
      private
      ...
      FMaxLen,FCurLen :  integer;
      
      FOnReceiveData : TOnReciveData;
      procedure DoReceiveData;
      procedure DoOnReceiveData(sender : Tobject;const MaxLen,CurLen : Integer);

      ...
      published
      ...
      property OnReveiceData : TOnReciveData read FOnReciveData  write FOnReciveData;
      end;procedure TSocketTransport.DoReciveData;
    begin
      DoOnReciveData(self,FMaxLen,FCurLen);
    end;procedure TSocketTransport.DoOnReciveData(sender : Tobject;const MaxLen,CurLen : Integer);
    begin
      if Assigned(FOnReciveData) then FOnReciveData(Self,MaxLen,CurLen);
    end;
    找到 TSocketTransport的 Receive 函数,在里面加入
    function TDSocketTransport.Receive(WaitForInput: Boolean; Context: Integer): IDataBlock;
      ....  
      Result.Signature := Sig;
      P := Result.Memory;
      Inc(Integer(P), Result.BytesReserved);
      FMaxLen := StreamLen; 
      FCurLen := 0;
      if Fmaxlen > 0 then
      DoReceiveData;

      ...
        if RetLen > 0 then
        begin
          Dec(StreamLen, RetLen);
          Inc(Integer(P), RetLen);
          CurLen := CurLen + RetLen;  
          DoReceiveData;

        end;  
      ...
      Fmaxlen := 0;
      FCurLen := 0;
      DoReceiveData;

    end;
    然后改 TSocketConnection TSocketConnection = class(TStreamedConnection)
      private
      ...
      FOnReceiveData : TOnReciveData;
      procedure DoOnReceiveData(sender : Tobject;const MaxLen,CurLen : Integer);

      published
      ...
      property OnReveiceData : TOnReciveData read FOnReceiveData  write FOnReceiveData;
      end;procedure TSocketConnection.DoOnReceiveData(sender : Tobject;const MaxLen,CurLen : Integer);
    begin
      if Assigned(FOnReceiveData) then FOnReceiveData(Self,MaxLen,CurLen);
    end;
    然后改这个部分,在里面最后加上红色部分
    function TDSockConnect.CreateTransport: ITransport;
    ....
      SocketTransport.OnReveiceData := DoOnReceiveData;
    end;原理基本上就是这样,自己可以灵活掌握,也可以重新写个控件。
      

  3.   

    压缩可以delphi自带的zlib单元.传输可用indy.这是最简单的。以下是我改了下indy demo的代码。给你参考一下。
    Client Codeprocedure DownFile();
    const
      c_PackLen = $1000;  //1K
    var
      SResponse : String;
      fStream   : TFileStream;
      dcStream  : TDecompressionStream;  fSize     : Integer;
      iRcvLen   : Integer;
    begin
      with TCPClient do
      begin
        Connect;    while Connected do
        begin
          fStream := TFileStream.Create(FileName, fmCreate or fmOpenWrite);
          try
            //Decompression
            dcStream := TDecompressionStream.Create(fStream);
            try
              // banner means the server thread is running
              SResponse := UpperCase(ReadLn);
              if Pos('BEG', SResponse) = 0 then Break;          fSize := StrToInt(Copy(SResponse, 4, Length(SResponse) - 3));
              //Progress
              pbDown.Max := fSize;
              pbDown.Postion := 0;          repeat
                // request file data
                WriteLn('SENDFILE');            { read all bytes until disconnected
                  length er in stream }
                iRcvLen := ReadInteger();
                ReadStream(dcStream, iRcvLen, True);            pbDown.Postion := pbDown.Postion + iRcvLen;          until iRcvLen < c_PackLen;        finally
              dcStream.Free;
            end;
          finally
    Disconnect;
            fStream.Free;
          end;
        end;
      end;
    end;
    Server Codeprocedure TForm1.TCPServerExecute(AThread: TIdPeerThread);
    const
      c_PackLen = $1000;  //1K
    var
      fStream : TFileStream;
      cStream : TCompressionStream;  iSendLen: Integer;
    begin
      with AThread.Connection do
      begin
        fStream := TFileStream(FileName, fmOpenRead or fmShareDenyNone);
        try
          //Compression
          cStream := TCompressionStream.Create(clFastest, fStream);
          try
            WriteLn('BEG' + IntToStr(fStream.Size));        repeat
              iSendLen := Min(c_PackLen, fStream.Size - fStream.Postion);          OpenWriteBuffer;
              try
                WriteStream(cStream, False, True, iSendLen);
              finally
                CloseWriteBuffer;
              end;
            until iSendLen < c_PackLen;
          finally
            cStream.Free;
          end;
        finally
          Disconnect;
          fStream.free;
        end;
      end;
    end;
      

  4.   

    to esunzsq :
    不用INDY,必须用socketconnection实现