Delphi 我可以获取Indy TCP连接缓冲区中尚未传输的字节大小吗?

Delphi 我可以获取Indy TCP连接缓冲区中尚未传输的字节大小吗?,delphi,tcp,indy,delphi-10.3-rio,Delphi,Tcp,Indy,Delphi 10.3 Rio,我想使用Indy TCP以尽可能快的速度通过internet连接发送一些(大)文件。我编写了一个简单的应用程序来测试Indy TCP客户机-服务器连接的工作原理 我发现的是: 所有对套接字的写入都会立即发生 即使在我写入后断开连接,如果数据被读取,数据仍会在另一侧接收 数据可以有任何大小;我写了100MB,我收到了每一位 这意味着套接字上有一个写入的传输缓冲区。看起来它可以有任何尺寸。。。如果我写了大量的数据(比如说100 MB),我认为它不是在一次操作中传输的,而是在一个小窗口中传输的(比

我想使用Indy TCP以尽可能快的速度通过internet连接发送一些(大)文件。我编写了一个简单的应用程序来测试Indy TCP客户机-服务器连接的工作原理

我发现的是:

  • 所有对套接字的写入都会立即发生
  • 即使在我写入后断开连接,如果数据被读取,数据仍会在另一侧接收
  • 数据可以有任何大小;我写了100MB,我收到了每一位
这意味着套接字上有一个写入的传输缓冲区。看起来它可以有任何尺寸。。。如果我写了大量的数据(比如说100 MB),我认为它不是在一次操作中传输的,而是在一个小窗口中传输的(比如说1 MB)。因此,当数据传输时,该缓冲区会收缩,直到在传输所有数据时达到零。我需要的是在任何时候缓冲区的长度,以便知道何时需要填充缓冲区,这样我就可以在不占用整个计算机内存的情况下连续写入

我不知道我在这里写的是否有意义。。。如果没有,请告诉我删除该问题并提出一个更一般的问题。最后,我想要的是通过Indy TCP连接以尽可能高的速度(即异步)发送一个文件,但带有一个进度条和一个取消按钮

这是测试应用程序:

procedure TClient.Execute;
var Cmd: Cardinal;
    Txt: String;
    Buff: TIdBytes;
    Size: Integer;
begin
 Size:= 5000000;
 SetLength(Buff, Size);
 Buff[0]:= 33;
 Buff[Size-1]:= 55;

 Client.Connect;
 Cmd:= 1234;
 Client.Socket.Write(Cmd);
 Client.Socket.Write(Size);
 Client.Socket.Write(Buff);
 Txt:= 'client finished transmision';
 SendMessage(RWnd, WM_USER, WPARAM(@Txt), 0);
 Client.Disconnect;
 Txt:= 'client disconected';
 SendMessage(RWnd, WM_USER, WPARAM(@Txt), 0);
end;

procedure TForm1.ServerExecute(AContext: TIdContext);
var Cmd: Cardinal;
    Mess: String;
    Buff: TIdBytes;
    Size: Integer;
begin
  Mess:= 'Server ready';
  SendMessage(Handle, WM_USER, WPARAM(@Mess), 0);

  Cmd:= AContext.Connection.Socket.ReadUInt32;
  Mess:= 'Server receive command';
  SendMessage(Handle, WM_USER, WPARAM(@Mess), 0);

  if Cmd = 1234 then begin
   Size:= AContext.Connection.Socket.ReadInt32;
   Sleep(4000);
   Mess:= 'Server start reading';
   SendMessage(Handle, WM_USER, WPARAM(@Mess), 0);
   AContext.Connection.Socket.ReadBytes(Buff, Size);
   Mess:= IntToStr(Buff[0]) + ' / ' + IntToStr(Buff[Size-1]);
   SendMessage(Handle, WM_USER, WPARAM(@Mess), 0);
  end;

  Mess:= 'Server closed connection';
  SendMessage(Handle, WM_USER, WPARAM(@Mess), 0);
end;

这取决于tcp上的协议。在传输开始时发送完整的文件大小或作为头属性发送我不认为这取决于我的协议。。。这更像是印地的内部机制。。。如果不是低级的东西。。。我可以一次将整个文件写入连接套接字,但是我没有那么多RAM(用于这个内部缓冲区)。我想为这个缓冲区设置一个最大值,当数据以另一个大小读取并清空时,向它写入更多的数据,这样传输就可以连续进行……但是你也可以这样做,我也写了写缓冲区在操作系统内核的套接字内部。您无法知道在任何给定时刻写入缓冲区中有多少数据。您只能知道您要求将多少数据放入缓冲区,您可以要求操作系统预先调整缓冲区的大小(但不能保证它会满足该请求)。要显示进度条,不需要知道实际的缓冲区内容。只需显示您请求发送的数据百分比。@MarusNebunu您不需要手动处理。发送尽可能多的数据,尽可能快。TCP将为您执行必要的限制。如果写入缓冲区已满,它将阻止您发送更多数据,直到空间清空为止。如果在发送更多数据之前缓冲区已清除,则在您自己的代码中发送速度不够快。