zoukankan      html  css  js  c++  java
  • Delphi IdTCPClient IdTCPServer 点对点传送文件

    https://blog.csdn.net/luojianfeng/article/details/53959175

    Delphi     IdTCPClient 点对点传送文件


    客户端向另一个客户端传送文件,不通过服务端中转
    那一个很重要的点是,这个客户端也要放一个IdTCPServer,也就是说这个客户端既是客户端,当接收文件的时候也是服务端,必须相应其它客户


    端对它的连接,这个时候客户端相当与服务端,好了,明白这个道理就好办了


    A客户端(放一个IdTCPClient控件,发送文件)

    procedure TFormFileSend.FormShow(Sender: TObject);//连接到服务端,同时自己变成服务端
    begin

      //自己变成服务端
      IdTCPServer1.Bindings.Clear;
      IdTCPServer1.Bindings.Add.IP:='192.168.252.1';
      IdTCPServer1.Bindings.Add.Port:=8831;
      IdTCPServer1.Active:=true;
      if  IdTCPServer1.Active then
      begin
        Memo1.Lines.Add('服务器已启动');
      end
      else
      begin
        Memo1.Lines.Add('服务器已停止');
      end;

      //连接到服务端
      IdTCPClient1.Host:=FormMain.host;//'192.168.252.1';
      IdTCPClient1.Port:=StrToInt(FormMain.port);//8829;
      if IdTCPClient1.Connected then
        IdTCPClient1.Disconnect;
      Try
        IdTCPClient1.Connect;
        IdTCPClient1.WriteLn(FormMain.qm+'|'+FormMain.bh);
      except
        MessageBox(Handle,'服务器没有开启','提示',MB_OK);
        Exit;
      end;


      loading();//连接到服务端,显示上线的客户端
    end;


    procedure TFormFileSend.loading();
    var
      Node: TTreeNode;
    begin
      RzCheckTree1.Items.Clear;


      sleep(500);//这里一定要延时,不然下面的数据明明有,但是读不出来, 2016-12-31
      
      with ADOQuery2 do
      begin
        SQL.Clear;
        SQL.Add('select a.ip,a.bh,a.qm,c.qm as bm from ipdz a left join zy b on a.bh=b.bh left join bm c on b.szbm=c.bh ');
        Open;
        while not Eof do
        begin
          Node := RzCheckTree1.Items.AddChild(nil,FieldByName('qm').AsString+'('+FieldByName('bm').AsString+')'+FieldByName('ip').AsString);
          Node.Data:=strnew(PChar(FieldByName('ip').AsString));
          Next;
        end;
      end;
    end;



    procedure TFormFileSend.SpeedButton1Click(Sender: TObject);//发送文件
    var
      iFileHandle:integer;
      iFileLen,cnt:integer;
      buf:array[0..4096] of byte;


      i: integer;
      zt:Boolean;
    begin
      if Edit1.Text='' then
      begin
        ShowMessage('请选择要上传的文件');
        Exit;
      end;


      zt:=False;
      for i:=0 to RzCheckTree1.Items.Count - 1 do
      begin
        if RzCheckTree1.ItemState[i] = cschecked then
        begin
          zt:=True;
        end;
      end;
      if zt=False then
      begin
        Application.MessageBox('请选择接收人!','提示',64);
        exit;
      end;


      for i:=0 to RzCheckTree1.Items.Count - 1 do
      begin
        if RzCheckTree1.ItemState[i] = cschecked then
        begin
          IdTCPClient2.Host:=PChar(RzCheckTree1.Items.Item[i].Data);
          IdTCPClient2.Port:=8831;
          if IdTCPClient2.Connected then
            IdTCPClient2.Disconnect;
          Try
            IdTCPClient2.Connect;
          except
            Memo1.Lines.Add(RzCheckTree1.Items.Item[i].Text+'不在线');
            continue;
          end;


          iFileHandle:=FileOpen(Edit1.Text,fmOpenRead);
          iFileLen:=FileSeek(iFileHandle,0,2);
          FileSeek(iFileHandle,0,0);
          ProgressBar1.Max:=iFileLen;
          ProgressBar1.Position := 0;
          IdTCPClient2.WriteLn(ExtractFileName(Edit1.Text)+'|'+IntToStr(iFileLen));
          while true do
          begin
            Application.ProcessMessages;
            cnt:=FileRead(iFileHandle,buf,4096);
            IdTCPClient2.WriteBuffer(buf,cnt);
            ProgressBar1.Position:=ProgressBar1.Position + cnt;
            Memo1.Lines.Add('正在传送文件...'+DateTimeToStr(Now));
            if cnt<4096 then
              break;
          end;
          FileClose(iFileHandle);
          Memo1.Lines.Add('文件传送完成!'+DateTimeToStr(Now));
        end;
      end;

    end;

    procedure TFormFileSend.SpeedButton5Click(Sender: TObject);//取消发送
    var
      i:Integer;
    begin
      FileClose(iFileHandle);
      IdTCPClient2.Disconnect;


      for i:=0 to RzCheckTree1.Items.Count - 1 do
      begin
        if RzCheckTree1.ItemState[i] = cschecked then
        begin
          IdTCPClient2.Host:=PChar(RzCheckTree1.Items.Item[i].Data);
          IdTCPClient2.Port:=8831;
          if IdTCPClient2.Connected then
            IdTCPClient2.Disconnect;
          Try
            IdTCPClient2.Connect;
          except
            Memo1.Lines.Add(RzCheckTree1.Items.Item[i].Text+'不在线');
            continue;
          end;


          IdTCPClient2.WriteLn('取消发送');
          IdTCPClient2.Disconnect;
        end;
      end;


      //Sleep(500);
      Memo1.Lines.Add('取消文件发送'+DateTimeToStr(Now));
    end;



    B客户端(要放一个IdTCPServer控件,相当于服务端接收)


    procedure TFormFileSend.IdTCPServer1Execute(AThread: TIdPeerThread);
    var
      rbyte:array[0..4096] of byte;
      sFile:TFileStream;
      cmd,FileSize:integer;
      str,FileName:string;
    begin
      if not AThread.Terminated and AThread.Connection.Connected then  //注意这里
      begin
        with AThread.Connection do
        begin
          Try
            str:=AThread.Connection.ReadLn;
            if POS('|',str)>0 then
            begin
              cmd:=pos('|',str); //查找分隔符
              FileName:=copy(str,1,cmd-1); //提取文件名
              FileSize:=StrToInt(copy(str,cmd+1,Length(str)-cmd+1)); //提取文件大小
              if MessageBox(0,Pchar('您有文件 "'+FileName+'" 您是接受还是拒绝?'),'文件接受',MB_YesNo or MB_ICONQUESTION)=ID_Yes 


    then //询问是否接收
              begin
                  ProgressBar1.Max:=FileSize div 100;   //初始化进度条
                  ProgressBar1.Position:=0;
                  SaveDialog1.FileName:=FileName; //指定保存的默认文件名,一定要在 SaveDialog1.Execute;之前,不然文件名为空
                  SaveDialog1.Execute;
                  sFile:=TFileStream.Create(SaveDialog1.FileName,fmCreate); //创建待写入的文件流
                  While FileSize>4096 do
                  begin
                    Application.ProcessMessages;


                    AThread.Connection.ReadBuffer(rbyte,4096);// 读取文件流


                    ProgressBar1.Position:=ProgressBar1.Position + (4096 div 100); //更新显示进度
                    Memo1.Lines.Add('正在接收文件中...'+DateTimeToStr(Now));


                    sFile.Write(rByte,4096);      //写入文件流
                    inc(FileSize,-4096);
                  end;
                  AThread.Connection.ReadBuffer(rbyte,FileSize);// .ReadBuffer(rbyte,iLen);
                  sFile.Write(rByte,FileSize);
                  sFile.Free;
                  Memo1.Lines.Add('文件接收完成!'+DateTimeToStr(Now));
              end;
            end;
          Finally
            //Disconnect;//断开连接
          end;
        end;
      end;      
    end;
  • 相关阅读:
    漫谈施工企业信息化规划(修订)
    SOAOffice 中间件,北京科翰软件
    组建“建筑施工企业信息化技术交流”QQ群(102226121),欢迎参与!
    国产、免费业务流程梳理工具SAM,炎黄盈动公司产品
    (参考)OpenExpressApp架构-信息系统开发平台
    逍遥笔输入法,哈!
    昨天开了一天的会!!
    昨天回到北京了!
    幸福是什么?
    周末辽宁兴城
  • 原文地址:https://www.cnblogs.com/tc310/p/9125988.html
Copyright © 2011-2022 走看看