【问题标题】:how to send file from server to client using indy如何使用 indy 将文件从服务器发送到客户端
【发布时间】:2018-04-29 07:51:10
【问题描述】:

我找一个例子,如何从服务器接收文件(我使用 Indy) 我想向服务器发送一些需求

在客户端:

MyIdTCPClient.IOHandler.WriteLn('SEND_FILE');
MyIdTCPClient.IOHandler.WriteLn('1.XLS');

在服务器上

procedure TServerMainForm.IdTCPServerExecute(AContext: TIdContext); 
var AStream : TMemoryStream;
    filesize : Integer;
    line, filename: String;
begin

    line := AContext.Connection.IOHandler.ReadLn();
        if line = 'SEND_FILE' then
        begin
            filename := AContext.Connection.IOHandler.ReadLn();

            AStream := TIdFileStream.Create(filename, fmOpenRead + fmShareDenyNone);
           try
               AContext.Connection.IOHandler.Write('FILE_DOWNLOAD'); //send command "FILE"
               AContext.Connection.IOHandler.Write(ExtractFilename(filename)); // send file name
               AContext.Connection.IOHandler.Write(IntToStr(AStream.Size)); //send file size

               AContext.Connection.IOHandler.Write(AStream);
           finally
               FreeAndNil(AStream);

           end;

然后在客户端

if MyIdTCPClient.IOHandler.InputBufferIsEmpty then
  begin
    MyIdTCPClient.IOHandler.CheckForDataOnSource(10);
    if MyIdTCPClient.IOHandler.InputBufferIsEmpty then Exit;
  end;
  S := MyIdTCPClient.IOHandler.ReadLn();

  if S = 'FILE_DOWNLOAD' then
  begin
        MyIdTCPClient.IOHandler.LargeStream := True; 

        if MyIdTCPClient.IOHandler.InputBufferIsEmpty then
        begin
          MyIdTCPClient.IOHandler.CheckForDataOnSource(10);
          if MyIdTCPClient.IOHandler.InputBufferIsEmpty then Exit;
        end;

         Filename :=  MyIdTCPClient.IOHandler.ReadLn(); //filename
            S := MyIdTCPClient.IOHandler.ReadLn(); // filesize
            FileSize := StrToInt(S);
            AStream := TIDFileStream.Create(ExtractFilePath(Paramstr(0)) + '\XLS\' + Filename, fmCreate);
            try
                AContext.Connection.IOHandler.ReadStream(AStream, Filesize, False);
            finally
                FreeAndNil(AStream);
            end;

但它不起作用。 客户端上没有创建任何文件; 你能帮帮我吗?

【问题讨论】:

    标签: delphi indy


    【解决方案1】:

    发送FILE_DOWNLOAD 回复时,服务器调用IOHandler.Write(String) 而不是IOHandler.WriteLn() 来发送FILE_DOWNLOAD 和文件名字符串。字符串没有以CRLF 终止,但客户端正在使用ReadLn() 来读取这些字符串。所以它永远不会尝试创建文件并读入它。

    话虽如此,我会为您的协议和代码建议一种稍微替代的设计。

    您不需要单独发送文件名。它们应该与它们所属的命令位于同一行。

    TIdIOHandler.Write(TStream)TIdIOHandler.ReadString() 可以为您处理发送/读取流大小。您不需要手动发送/读取大小,当然也不需要作为字符串。

    试试这个:

    客户

    var
      XLSFolder: string;
    
    ...
    
    MyIdTCPClient.IOHandler.WriteLn('SEND_FILE 1.XLS');
    
    ...
    
    if MyIdTCPClient.IOHandler.InputBufferIsEmpty then
    begin
      MyIdTCPClient.IOHandler.CheckForDataOnSource(10);
      if MyIdTCPClient.IOHandler.InputBufferIsEmpty then Exit;
    end;
    S := MyIdTCPClient.IOHandler.ReadLn();
    Cmd := Fetch(S);
    if Cmd = 'FILE_DOWNLOAD' then
    begin
      AStream := TFileStream.Create(XLSFolder + S, fmCreate);
      try
        MyIdTCPClient.IOHandler.LargeStream := True;
        MyIdTCPClient.IOHandler.ReadStream(AStream, -1, False);
      finally
        AStream.Free;
      end;
    end;
    
    ...
    
    initialization
      XLSFolder := ExtractFilePath(Paramstr(0)) + 'XLS\';
    

    服务器

    procedure TServerMainForm.IdTCPServerExecute(AContext: TIdContext);
    var
      AStream : TFileStream;
      cmd, params, filename: String;
    begin
      params := AContext.Connection.IOHandler.ReadLn();
      cmd := Fetch(params);
      if cmd = 'SEND_FILE' then
      begin
        filename := ExtractFilename(params);
        try
          AStream := TFileStream.Create('<some path>\' + filename, fmOpenRead or fmShareDenyWrite);
        except
          AContext.Connection.IOHandler.WriteLn('FILE_DOWNLOAD_ERR ' + filename);
          Exit;
        end;
        try
          AContext.Connection.IOHandler.WriteLn('FILE_DOWNLOAD ' + filename);
          AContext.Connection.IOHandler.LargeStream := True;
          AContext.Connection.IOHandler.Write(AStream, 0, True);
        finally
          AStream.Free;
        end;
      end;
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-02
      • 2011-04-04
      • 1970-01-01
      • 2012-02-24
      • 2018-09-24
      • 2015-02-06
      • 1970-01-01
      相关资源
      最近更新 更多