gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 02:48:42 26 4
gpt4 key购买 nike

我同时开发了两个软件。

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

我可以在服务器和客户端之间毫无问题地发送数据,然而,从服务器到客户端的数据传输速度对我来说是个问题。

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

Indy 10 以 1024 字节 block 的形式发送数据,我可以使用 NSLog() 在我的 iOS 应用程序中看到这一点。

问题:如何更改 Indy 10 的行为以一次发送更大的数据 block ?

编辑:我正在使用以下代码发送 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;

最佳答案

Indy 不是限制发送数据包大小的工具。当从 TMemoryStream 读取时,其默认缓冲区大小为 32K(请参阅 TIdIOHandler.SendBufferSize 属性)(仅受读取时可用内存的限制),然后传递任意多个字节被读取到底层套接字以进行发送。

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

socket - Linux socket interface

Socket options

The socket options listed below can be set by using setsockopt(2) and read with getsockopt(2) with the socket level set to SOL_SOCKET for all sockets. Unless otherwise noted, optval is a pointer to an int.

...

SO_SNDBUF
Sets or gets the maximum socket send buffer in bytes. The kernel doubles this value (to allow space for bookkeeping overhead) when it is set using setsockopt(2), and this doubled value is returned by getsockopt(2). The default value is set by the /proc/sys/net/core/wmem_default file and the maximum allowed value is set by the /proc/sys/net/core/wmem_max file. The minimum (doubled) value for this option is 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 的限制。确保您的 iOS 应用在从 stream 事件处理程序中的 NSInputStream 读取时未将其输入缓冲区限制为 1024 字节。

关于linux - Indy 10 以 1024 个 block 发送数据。如何增加 block 大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32999006/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com