Delphi IdTCPClient IdTCPServer 點對點傳送文件

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

 

Delphi     IdTCPClient 點對點傳送文件


客戶端向另外一個客戶端傳送文件,不經過服務端中轉
那一個很重要的點是,這個客戶端也要放一個IdTCPServer,也就是說這個客戶端既是客戶端,當接收文件的時候也是服務端,必須相應其它客戶


端對它的鏈接,這個時候客戶端至關與服務端,好了,明白這個道理就好辦了


A客戶端(放一個IdTCPClient控件,發送文件)服務器

 

procedure TFormFileSend.FormShow(Sender: TObject);//鏈接到服務端,同時本身變成服務端
beginflex

  //本身變成服務端
  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;spa



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;.net

 

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;orm

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;
相關文章
相關標籤/搜索