delphi indy10 tcpserver/client 收发文件

 indy10 和9  tcpserver 有区别,虽然都是线程,但10  要得到线程必须引用 IdSchedulerOfThread,idcontext

然后 TIdYarnOfThread(acontext.yarn).thread  获取线程

收发命令  都 在 acontext.connection.iohandle 

 

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  IdCustomTCPServer, IdTCPServer, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdContext, IdSchedulerOfThread, IdGlobal, Vcl.ComCtrls;

type
  TForm1 = class(TForm)
    IdTCPClient1: TIdTCPClient;
    IdTCPServer1: TIdTCPServer;
    btn1: TButton;
    btn2: TButton;
    Button1: TButton;
    mmo1: TMemo;
    dlgOpen1: TOpenDialog;
    ProgressBar1: TProgressBar;
    procedure btn1Click(Sender: TObject);
    procedure IdTCPServer1Connect(AContext: TIdContext);
    procedure IdTCPServer1Execute(AContext: TIdContext);
    procedure Button1Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
begin
  IdTCPServer1.Bindings.Add.IP := '127.0.0.1';
  IdTCPServer1.Bindings.Add.Port := 2222;
  IdTCPServer1.Active := True;
end;

procedure TForm1.btn2Click(Sender: TObject);
begin
  IdTCPClient1.Host := '127.0.0.1';
  IdTCPClient1.Port := 2222;
  IdTCPClient1.Connect;
end;

//发送事件

procedure TForm1.Button1Click(Sender: TObject);
var
  iFileHandle: integer;
  iFileLen, cnt: integer;
  buf: TIdBytes;
  lfilename: string;
  ln: Cardinal;
begin
  if dlgOpen1.Execute then
  begin
    lfilename := dlgOpen1.FileName;
  end;
  if lfilename <> '' then
  begin
    SetLength(buf, 4096);
    iFileHandle := FileOpen(lfilename, fmOpenRead);
    iFileLen := FileSeek(iFileHandle, 0, 2);
    FileSeek(iFileHandle, 0, 0);
    ProgressBar1.Max := iFileLen;
    ProgressBar1.Position := 0;
    IdTCPClient1.IOHandler.WriteLn(ExtractFileName(lfilename) + '|' + IntToStr(iFileLen));
    while true do
    begin
      Application.ProcessMessages;
      cnt := FileRead(iFileHandle, buf[0], 4096);
      ln := GetLastError;
      IdTCPClient1.IOHandler.Write(buf, cnt);
      ProgressBar1.Position := ProgressBar1.Position + cnt;
      mmo1.Lines.Add('正在传送文件...' + DateTimeToStr(Now));
      if cnt < 4096 then
        break;
    end;
    FileClose(iFileHandle);
    mmo1.Lines.Add('文件传送完成!' + DateTimeToStr(Now));

    SetLength(buf, 0);
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  IdTCPClient1.Disconnect;
  IdTCPServer1.Active := false;
end;

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin
  mmo1.Lines.Add(AContext.Binding.IP + '上线');
end;


//接收事件

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
  rbyte: TIdBytes;
  sFile: TFileStream;
  cmd, FileSize: integer;
  str, FileName: string;
begin
  if not TIdYarnOfThread(AContext.Yarn).Thread.Terminated and AContext.Connection.Connected then  //注意这里
  begin
    with AContext.Connection do
    begin
      try
        str := IOHandler.ReadLn;   //接收文件大小及文件名
        cmd := pos('|', str); //查找分隔符
        FileName := copy(str, 1, cmd - 1); //提取文件名
        FileSize := StrToInt(copy(str, cmd + 1, Length(str) - cmd + 1)); //提取文件大小

        sFile := TFileStream.Create(ExtractFilePath(ParamStr(0)) + '\' + FileName, fmCreate);
        while FileSize > 4096 do
        begin
          Application.ProcessMessages;
          IOHandler.ReadBytes(rbyte, 4096,False); // 读取文件流  这里要注意 必须 false
          sFile.Write(rbyte[0], 4096);      //写入文件流
          mmo1.Lines.Add('正在接收文件中...' + DateTimeToStr(Now));
          inc(FileSize, -4096);
        end;
        IOHandler.readbytes(rbyte, FileSize);
        sFile.Write(rbyte[0], FileSize);
        sFile.Free;
        mmo1.Lines.Add('文件接收完成!' + DateTimeToStr(Now));

      finally

      end;
    end;
  end;

end;

end.

 

 

你可能感兴趣的:(delphi)