首页 > 解决方案 > 如何在 C 中使用 send() 计算字节数,包括协议大小?

问题描述

我正在尝试从我的程序中计算总发送字节数,但我无法获得准确的值。我的所有函数都调用一个函数,该函数使用 send() 函数将数据发送到我的服务器。在这个函数中,我得到 send() 的返回并将总和到全局计数器。这工作正常。但是当我与“iftop”实用程序(sudo iftop -f 'port 33755')进行比较时,我在 iftop 上获得了更多数据,然后在我的应用程序中获得了更多数据……我猜是不是因为 tcp 标头/协议数据。我真的不知道如何计算这个。我正在使用 send() 和可变数据长度发送数据包,所以我不确定是否可以从那里检测/计算 TCP 数据包大小。我知道每个 TCP 数据包都会发送 TCP 标头,但我不确定发送了多少数据包。我可以假设每次调用 send(),如果数据长度小于 1518(TCP 数据包大小限制?),比它只有一个 TCP 数据包,我需要总结 TCP 标头长度吗?即使我发送了一个字节?如果是这样,这些来自 TCP 结构的额外字节有多少?!

有关信息:我在 linux 上使用 GCC 作为编译器。

谢!

标签: csockets

解决方案


如何在 C 中使用 send() 计算字节数,包括协议大小?

在您的程序中没有可靠的方法可以做到这一点。您可以计算传输您计算的总有效负载大小的数据所需的最小总字节数,但需要进行一些假设,但您需要从内核端进行监视以确定确切的字节数。

我可以假设每次调用 send(),如果数据长度小于 1518(TCP 数据包大小限制?),那么它只是一个 TCP 数据包,我需要对 TCP 标头长度求和?

不,这不是一个安全的假设。主要问题是内核不一定将每次send()调用传输的数据与其自己的数据包序列相匹配。它可以将来自多个send()s 的数据组合成更少数量的数据包。此外,它可能使用比以太网默认的 1500 字节更小的 MTU 或更大的 MTU,这取决于各种因素,此外,您需要将数据包标头放入所选 MTU,因此一个数据包携带的有效负载是比那个小。

我怀疑你让这太难了。如果这是分配给您的任务(例如,家庭作业问题),那么我的第一个猜测是您只计算总有效负载大小,而不是协议开销。或者,如果您确实需要考虑开销,那么我的猜测是您应该根据网络的测量或假设特征来估计。如果您为自己设置了这个问题,那么我只能说人们通常会进行我刚才描述的两种计算之一,而不是您询问的那个。


推荐阅读