Indy 10以1024个块发送数据。如何增加块大小?

时间:2015-10-07 17:43:30

标签: linux performance tcp lazarus indy10

我已经开发了两个软件。

一个是用于iOS设备的TCP客户端,它是在XCode中开发的, 另一个是用于Linux OS的TCP服务器,它是在Lazarus中使用Indy 10作为网络框架开发的。

我可以在服务器和客户端之间发送数据,没有任何重大问题, 但是从服务器到客户端的数据传输速度对我来说是一个问题。

从iOS客户端向Linux服务器发送数据时,我的传输速度非常高,每秒高达20 MB, 但是当从Linux服务器向iOS客户端发送数据时,我每秒只能达到100千字节(100kb)。

Indy 10以1024字节的块发送数据,我可以使用NSLog()在我的iOS应用中看到。

问题:如何更改Indy 10的行为,以便一次发送更大的块?

修改 我使用以下代码发送TMemoryStream

procedure TMyClass.SendData(aData: TMemoryStream);
  var i: integer;
      ctx : TIdContext;
begin
  aData.Position := 0;
  with fIdTCP.Contexts.LockList do
  begin
    for i := 0 to Count -1 do //I'm broadcasting the data
    begin
      ctx := TIdContext(Items[i]);
      ctx.Connection.IOHandler.LargeStream:=true;
      ctx.Connection.IOHandler.Write(aData, aData.Size, false);
    end;

    ctx.Connection.IOHandler.WriteBufferClose;
    fIdTCP.Contexts.UnlockList;
  end   
end;

1 个答案:

答案 0 :(得分:2)

Indy不是限制发送数据包大小的人。从TIdIOHandler.SendBufferSize读取时,它的默认缓冲区大小为32K(参见TMemoryStream属性)(仅受读取时可用内存的限制),然后传递许多字节被读取到底层套接字以便发送

Linux可能是限制发送大小的那个。底层套接字的默认发送缓冲区大小可以是1024字节。 Linux文档说明如下:

socket - Linux socket interface

  

套接字选项

     

下面列出的套接字选项可以使用setsockopt(2)进行设置,并使用getsockopt(2)进行读取,套接字级别设置为SOL_SOCKET所有套接字。除非另有说明,否则optval是指向int的指针。

     

...

     

SO_SNDBUF
  以字节为单位设置或获取最大套接字发送缓冲区。当使用setsockopt(2)设置时,内核将此值加倍(以允许用于簿记开销的空间),并且getsockopt(2)返回此加倍值。默认值由/proc/sys/net/core/wmem_default文件设置,最大允许值由/proc/sys/net/core/wmem_max文件设置。 此选项的最小(加倍)值为2048

请检查您的Linux wmem_default / wmem_max配置是否将传输的数据包限制为1024字节。

您可以使用Indy的TIdSocketHandle.SetSockOpt()方法尝试指定不同的缓冲区大小(在Linux配置的限制范围内),例如:

uses
  ..., IdStackConsts;

procedure TMyForm.MyTCPServerConnect(AContext: TIdContext);
var
  BufferSize: Integer;
begin
  BufferSize := ...;
  AContext.Binding.SetSockOpt(Id_SOL_SOCKET, Id_SO_SNDBUF, BufferSize);
  AContext.Binding.GetSockOpt(Id_SOL_SOCKET, Id_SO_SNDBUF, BufferSize);
  // BufferSize now contains the ACTUAL buffer size used by the socket
  // which may be different than what you requested...
end;

如果缓冲区大小不受Linux限制,则在接收数据时可能会受到iOS的限制。从NSInputStream事件处理程序中的stream读取时,请确保您的iOS应用不会将其输入缓冲区限制为1024字节。