一次性将GB的“是”写入TCP套接字是一种好做法吗?

一次性将GB的“是”写入TCP套接字是一种好做法吗?,tcp,tcpsocket,Tcp,Tcpsocket,我正在维护一些成熟的生产代码,这些代码通过TCP套接字发送数据。它总是将大块数据分成许多数据包,每个数据包有1000字节。我只是想知道为什么会这样做。为什么我不能一次性将一个GB的字节数组写入套接字?这样做的缺点是什么?根据底层实现,尝试在一个块中发送1GB可能会导致1GB被复制到某个缓存中,然后在那里保留一段时间。因此,如果没有足够的可用内存,这可能是一个问题(即使有足够的可用内存,这也可能不是利用它的最有效方式) 虽然“手动”将其拆分为1000字节的段,但对我来说,每个字节听起来都有点过分。

我正在维护一些成熟的生产代码,这些代码通过TCP套接字发送数据。它总是将大块数据分成许多数据包,每个数据包有1000字节。我只是想知道为什么会这样做。为什么我不能一次性将一个GB的字节数组写入套接字?这样做的缺点是什么?

根据底层实现,尝试在一个块中发送1GB可能会导致1GB被复制到某个缓存中,然后在那里保留一段时间。因此,如果没有足够的可用内存,这可能是一个问题(即使有足够的可用内存,这也可能不是利用它的最有效方式)


虽然“手动”将其拆分为1000字节的段,但对我来说,每个字节听起来都有点过分。

根据底层实现的不同,尝试在一个块中发送1GB可能会导致1GB被复制到某个缓存中,然后在那里保留一段时间。因此,如果没有足够的可用内存,这可能是一个问题(即使有足够的可用内存,这也可能不是利用它的最有效方式)


虽然“手动”将其拆分为1000字节的段,但对我来说,每个字节听起来都有点像是杀伤力过大。

有很多理由不立即投入一大块

首先:即使在速度非常快的网络上,发送GB的数据也要花费大量的时间。在10Gbps网络上,这需要不到1秒的时间,这在计算机语言中是一个很长的时间。这就假设这个操作拥有网络的所有可用带宽,不必与其他任何操作共享

这意味着,如果您成功地对TCP套接字执行1GB
write
调用,则需要一段时间才能真正发送后面的数据位

在这段时间里,你必须把所有的数据都保存在内存中。这意味着您需要为整个事务分配并保留1GB的数据

如果您在每次写入之前填充一个小的ish缓冲区并从源代码读取(或生成,具体取决于数据的来源),那么您只需要一点内存(缓冲区的大小)

所有这些对今天的机器来说可能不是什么大问题,但是考虑到许多服务器会同时服务数百个客户机/请求,如果每个都需要一个1GB的缓冲区,那么它很快就会失控。
1000是那个缓冲区的合适尺寸吗?我不是网络专家,但我觉得这有点低。也许64k这个数字比较合适,但其他人可以在这里提供更好的细节。找到一个好的缓冲区大小有时会有点棘手。

有很多理由不立即投入大量缓冲区

首先:即使在速度非常快的网络上,发送GB的数据也要花费大量的时间。在10Gbps网络上,这需要不到1秒的时间,这在计算机语言中是一个很长的时间。这就假设这个操作拥有网络的所有可用带宽,不必与其他任何操作共享

这意味着,如果您成功地对TCP套接字执行1GB
write
调用,则需要一段时间才能真正发送后面的数据位

在这段时间里,你必须把所有的数据都保存在内存中。这意味着您需要为整个事务分配并保留1GB的数据

如果您在每次写入之前填充一个小的ish缓冲区并从源代码读取(或生成,具体取决于数据的来源),那么您只需要一点内存(缓冲区的大小)

所有这些对今天的机器来说可能不是什么大问题,但是考虑到许多服务器会同时服务数百个客户机/请求,如果每个都需要一个1GB的缓冲区,那么它很快就会失控。 1000是那个缓冲区的合适尺寸吗?我不是网络专家,但我觉得这有点低。也许64k这个数字比较合适,但其他人可以在这里提供更好的细节。找到一个好的缓冲区大小有时有点棘手