Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 使用Indy将文件从服务器发送到客户端_Delphi_Tcpclient_Indy10 - Fatal编程技术网

Delphi 使用Indy将文件从服务器发送到客户端

Delphi 使用Indy将文件从服务器发送到客户端,delphi,tcpclient,indy10,Delphi,Tcpclient,Indy10,我有两个程序,一个用于服务器,另一个用于客户端 服务器向客户端发送一个文件。在客户端中,我使用TIdTCPClient、tidthreadscomponent和tidtantizone组件 文件创建得很好,但线程永远不会结束。调试时,我从未免费使用Fs.Free 这是我的客户代码: procedure TForm1.IdThreadComponentRun(Sender: TIdThreadComponent); var MsgDuServeur: string; Taille: Int

我有两个程序,一个用于服务器,另一个用于客户端

服务器向客户端发送一个文件。在客户端中,我使用TIdTCPClient、tidthreadscomponent和tidtantizone组件

文件创建得很好,但线程永远不会结束。调试时,我从未免费使用Fs.Free

这是我的客户代码:

procedure TForm1.IdThreadComponentRun(Sender: TIdThreadComponent);
var
  MsgDuServeur: string;
  Taille: Integer;
  Fs : TFileStream;
begin
  MsgDuServeur:= Trim(IdTCPClient.IOHandler.ReadLn(nil));
  MemoService.Lines.Add('Serveur : ' + MsgDuServeur);
  if (MsgDuServeur = 'RECUP_ENCOURS') then
  begin
    try
      Fs:= TFileStream.Create('C:\temp\client\1test.cds', fmCreate);
      try
        IdTCPClient.IOHandler.LargeStream:= True;
        Taille:= IdTCPClient.IOHandler.ReadInt64();
        IdTCPClient.IOHandler.ReadStream(Fs, -1, False); 
        IdThreadComponent1.Active:= False;
      finally
        Fs.Free;
      end;
    except
      on E: Exception do
      _MessageDlg(E.message, mtWarning, [mbOK], 0);
    end;
  end;
end;
这是我的服务器代码

procedure TServiceServeurTrf.IdTCPServerExecute(AContext: TIdContext);
var
  Flux: TMemoryStream;
  LStreamSize : int64;
begin
  try
    // Transfert de fichiers volumineux
    Context.Connection.Socket.WriteLn('RECUP_ENCOURS'); 
    AContext.Connection.IOHandler.LargeStream:= True;
    Flux:= TMemoryStream.Create;
    try
      Flux.LoadFromFile(C:\Windows\Temp\Transfert\3000\1test.cds);
      Flux.Position:= 0;
      AContext.Connection.IOHandler.Write(Flux.Size);
      AContext.Connection.IOHandler.Write(Flux, 0, True);
    finally
      FreeAndNil(Flux);
    end;
  except
    EcrireLog('Erreur');
  end;
end;
我删除了防冻液,在ReadStream之后,我使用IdThreadComponent1。Active:=False;现在没事了。 如何同步?事实上,我希望将progressbar与IdTCPClientWork、IdTCPClientWorkBegin、IdTCPClientWorkEnd一起使用,但我看不到它的进度,因为您误用了TIdIOHandler.WriteTStream和TIdIOHandler.ReadStream方法

在客户端,将ReadStream的AByteCount参数设置为-1,将AReadUntilDisconnect参数设置为False(默认值)会导致ReadStream在读取流数据之前为您读取流大小,其中,根据LargeStream属性,使用ReadInt32或ReadInt64读取流大小

最初,您的客户端调用ReadInt64并将结果保存为整数!然后调用ReadStream,将AByteCount设置为ReadInt64的结果,并将AReadUntilDisconnect设置为True。因此,无论实际发送了多少字节,ReadStream都将无限期地读取,直到服务器关闭连接

然后您将客户端代码更改为调用ReadStream,AByteCount设置为-1,AReadUntilDisconnect设置为False,但您事先没有删除对ReadInt64的调用,因此现在您有了对流大小的双重读取

在服务器端,将AWriteByteCount参数设置为True会导致WriteStream在发送流数据之前发送流大小,其中大小是使用WriteInt32或WriteInt64发送的,具体取决于LargeStream属性。但是,您的服务器代码在调用WriteStream之前正在调用WriteInt64,所以您有一个流大小的双重发送

访问UI时,您也没有与主线程同步

请尝试以下方法:

过程TForm1.IdThreadComponentRunSender:TIdThreadComponent; 变量 MsgDuServeur:字符串; Fs:TFileStream; 开始 MsgDuServeur:=TrimIdTCPClient.IOHandler.ReadLn; TThread.Synchronize 程序 开始 MemoService.Lines.Add'Serveur:'+MsgDuServeur; 终止 ; 如果MsgDuServeur='RECUP_ENCOURS',则 开始 尝试 Fs:=TFileStream.Create'C:\temp\client\1test.cds',fmCreate; 尝试 IdTCPClient.IOHandler.LargeStream:=True;
IdTCPClient.IOHandler.ReadStreamFs,-1,False;//请将您的问题同时显示发送文件的服务器代码。但是,当您知道要发送的文件大小时,为什么要将ReadStream的AReadUntilDisconnect参数设置为True?它应该是假的。更好的方法是,如果将默认值设置为AByteCount=-1和AReadUntilDisconnect=False,那么ReadStream将为您处理ReadInt64。另外,仅供参考,对MemoService.Lines.Add和MessageDlg的调用需要与主UI线程同步,它们不能在工作线程中安全使用。如果你也在使用线程,为什么还要使用TID防冻剂呢?谢谢,我根据你的评论修改了我的源代码。我为你发布了一个答案。谢谢。我做了更改,但是当我删除IdThreadComponent1行时。Active:=False;在客户机中,第一次测试是可以的,但是当我关闭表单再次测试时,表单就不能了show@GB74这可能与停用线程无关。使用调试器确保您的客户端代码中其他地方没有我们看不到的问题。感谢您的帮助。下面是我的客户端代码我想使用progressbar,但我看不到progress@GB74那么您没有正确使用进度事件,但没有显示该代码。此外,事件是在读取/写入数据的同一线程中触发的,因此请确保在访问ProgressBar时同步对UI线程的访问。