想做一个类似CuteFtp或者FlashGet的文件传送工具,实现图片的上传,具有续传功能。目前的设计是将FileListBox中的一个或者多个文件拖放到ListView中,然后实现上传,应如何实现?请高手给点指点或者介绍一些网站,不胜感激!

解决方案 »

  1.   

    首先发指令给服务器,包含要上船的文件的信息,比如名称,大小,最好在发一个分割后的文件块的crc或者md5编码列表(最好用md5,不可逆算法),服务器接受到以后告诉客户端可以上船了,客户端上传一段文件后,服务器端对其进行校验,如果错误了,让其重发,否则就继续要求其他的分块,具体的接收进度,最好放在服务器端,服务器端根据该信息来确定从客户端那里什么位置开始接收就可以了,很简单的
      

  2.   

    wxjh(农民)  
     可以教小我怎么做吗?
     qq :57798768
      

  3.   

    我给你一个 文件传输的代码 ..服务器端:
    unit U_Server;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, IdBaseComponent, IdComponent, IdTCPServer, Math;type
      Tfrm_Server = class(TForm)
        IdTCPServer1: TIdTCPServer;
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        ProgressBar1: TProgressBar;
        StatusBar1: TStatusBar;
        Edit1: TEdit;
        Button4: TButton;
        OpenDialog1: TOpenDialog;
        Edit2: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        procedure Button1Click(Sender: TObject);
        procedure Button4Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure IdTCPServer1Execute(AThread: TIdPeerThread);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        AFileStream: TFileStream; //传输的文件流
        procedure ButtonBegin;
        procedure ButtonEnd;
        { Private declarations }
      public
        { Public declarations }
      end;var
      frm_Server: Tfrm_Server;implementation{$R *.dfm}procedure Tfrm_Server.Button1Click(Sender: TObject);
    begin
      if OpenDialog1.Execute then
        Edit1.Text := OpenDialog1.FileName;
    end;procedure Tfrm_Server.Button4Click(Sender: TObject);
    begin
      Close;
    end;procedure Tfrm_Server.Button2Click(Sender: TObject);
    begin
      if not FileExists(Edit1.Text) then //检测文件是否存在
      begin
        Showmessage('文件不存在,请选择文件!');
        exit;
      end;
      //建立文件流
      AFileStream := TFileStream.Create(Edit1.Text, fmOpenRead);
      ProgressBar1.Max := AFileStream.Size;
      ProgressBar1.Position := 0;
      ButtonBegin; //VCL开始状态设置
      //服务器准备好连接
      IdTCPServer1.DefaultPort := StrToIntDef(Edit2.Text, 9925);
      if not IdTCPServer1.Active then IdTCPServer1.Active := True;
    end;procedure Tfrm_Server.ButtonBegin;
    begin //VCL开始状态设置
      Button1.Enabled := False;
      Button2.Enabled := False;
      Button3.Enabled := True;
      Button4.Enabled := False;
    end;procedure Tfrm_Server.ButtonEnd;
    begin //VCL结束状态设置
      Button1.Enabled := True;
      Button2.Enabled := True;
      Button3.Enabled := False;
      Button4.Enabled := True;
    end;procedure Tfrm_Server.Button3Click(Sender: TObject);
    begin
      StatusBar1.SimpleText := '传输取消...';
      AFileStream.Free; //释放文件流
      ButtonEnd; //VCL结束状态设置
    end;procedure Tfrm_Server.IdTCPServer1Execute(AThread: TIdPeerThread);
    var
      cmd: string; //接收到客户端的字符串信息
      ASize: Integer; //需要传输的流大小
    begin
      with AThread.Connection do //已经连街上的一个进程
      begin
        cmd := UpperCase(ReadLn); //客户端发送的命令字符串
        if cmd = 'BEGIN' then //开始传输
        begin
          //告诉远程传输文件的大小和文件名
          WriteLn(Format('%d|%s', [AFileStream.Size, ExtractFileName(Edit1.Text)]));
          StatusBar1.SimpleText := '准备传输...';
          Exit;
        end;
        if cmd = 'END' then
        begin //传输完成
          Button3.Click;
          StatusBar1.SimpleText := '传输完成...';
          Exit;
        end;
        if cmd = 'CANCEL' then
        begin //传输取消
          StatusBar1.SimpleText := '传输取消...';
          //保持传输状态
          Exit;
        end;
        //按照指定位置传输文件
        AFileStream.Seek(StrToInT(cmd), soFromBeginning); //转到文件流传输的位置
        ASize := Min(AFileStream.Size - AFileStream.Position, RecvBufferSize);
        //计算需要发送的大小,Min()函数在Math单元
        OpenWriteBuffer; //准备发送缓冲
        WriteStream(AFileStream, false, false, ASize);
        //注意这个函数的参数。
        CloseWriteBuffer; //结束发送缓冲
        StatusBar1.SimpleText := Format('当前传输位置%s/大小%d', [cmd, AFileStream.Size]);
        ProgressBar1.Position := ProgressBar1.Position + ASize;
      end;
    end;procedure Tfrm_Server.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      IdTCPServer1.Active := False;
    end;end.客户端:unit U_Client;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, Math,
      StdCtrls, ComCtrls;type
      Tfrm_Client = class(TForm)
        SaveDialog1: TSaveDialog;
        IdTCPClient1: TIdTCPClient;
        Button1: TButton;
        StatusBar1: TStatusBar;
        Edit1: TEdit;
        Label1: TLabel;
        Edit2: TEdit;
        Label2: TLabel;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      frm_Client: Tfrm_Client;implementation{$R *.dfm}procedure Tfrm_Client.Button1Click(Sender: TObject);
    var
      cmd: string;
      ASize, TotalSize: Int64;
      AFileStream: TFileStream;
    begin
      IdTCPClient1.Host := Edit1.Text; //连接主机
      IdTCPClient1.Port := StrToIntDef(Edit2.Text, 9925); //端口
      IdTCPClient1.Connect; //连接
      try
        IdTCPClient1.WriteLn('BEGIN'); //提示服务器开始接收
        cmd := IdTCPClient1.ReadLn;
        //以“|”符号分离文件名
        SaveDialog1.FileName := Copy(cmd, Pos('|', cmd) + 1, Length(cmd));
        if not SaveDialog1.Execute then
        begin
          IdTCPClient1.WriteLn('CANCEL'); //告诉服务器取消
          IdTCPClient1.Disconnect; //断开连接
          exit;
        end;
        TotalSize := StrToInt(Copy(cmd, 0, Pos('|', cmd) - 1)); //分离文件大小
        //建立文件流准备接收
        AFileStream := TFileStream.Create(SaveDialog1.FileName, fmCreate);
        try //循环开始接受
          repeat
            IdTCPClient1.WriteLn(IntToStr(AFileStream.Size));//发送当前传输的位置
            ASize := Min(TotalSize - AFileStream.Size, IdTCPClient1.RecvBufferSize);
            //选择剩余大小和缓冲区大小小的一个作为传输的大小
            IdTCPClient1.ReadStream(AFileStream, ASize); //接收流
            StatusBar1.SimpleText := Format('当前传输位置%d/大小%d', [AFileStream.Size, TotalSize]);
            Application.ProcessMessages;
          until AFileStream.Size = TotalSize; //大小一致了表示结束
        finally
          AFileStream.Free; //释放文件流
        end;
        IdTCPClient1.WriteLn('END'); //提示服务器传输完成
        StatusBar1.SimpleText := '传输完成...';
      except
        StatusBar1.SimpleText := '连接服务器失败或者对方已经中断传输!';
      end;
      IdTCPClient1.Disconnect;
    end;end.
      

  4.   

    to grand_ness() :你的方法好象只能一个一个的传,如果服务端要传多个文件的话,这样就要求客户端和服务端都要配合才能传送。如何做到服务端传多个固定的文件,而只需要客户端自己下载就行了,也就是说服务端没有人员维护也能保证各个客户端能正常更新文件?