代码之家  ›  专栏  ›  技术社区  ›  Aditya Sehgal

原始套接字接收缓冲区

  •  2
  • Aditya Sehgal  · 技术社区  · 16 年前

    我们目前正在通过IP测试电信应用程序。我们打开一个原始套接字,从远程端接收消息(msgrate@750+msgs/second,大小约180字节,不包括IP)。

    在原始套接字的顶部有一个称为sctp(就像tcp)的层,它不时地指示它缺少一些数据包。现在,我们在接收节点上运行wireshark,我们可以在wireshark中看到这个包。

    在我看来,套接字的接收缓冲区很小,导致IP(?)删除消息。但是,ip-pegs(netstat-sv)不显示丢弃的数据包。我们已尝试将套接字接收队列设置为40000,但没有成功。

    如果我们要配置IP层的选项(如果有的话),或者需要设置任何特定的套接字选项,我将非常感谢任何指针。

    2 回复  |  直到 10 年前
        1
  •  2
  •   Aditya Sehgal    16 年前

    谢谢你的投入。然而,我们已经能够“解决”这个问题。 早些时候,我描述了我们如何阅读消息。 一旦select返回,我们将运行一个循环(调到要读取的原始消息数,在我们的例子中是1)。 1)我们调用ioctl(fionread)来查找要读取的字节数; 2)通过调用recvfrom读取那么多字节 3)向用户发送字节 4)再次进入循环,调用ioctl(fionread),然后重复这些步骤。

    但是,在第4点,ioctl(fionread)用于返回0。我们的代码有一个防御检查。它是预期的,来自ioctl(fionread)的0字节意味着发送方已经发送了一个负载为0的IP头。因此,它使用调用recvfrom(bytes to read=0)来清除IP头,以免select在这上面再次设置。

    在时间t0,ioctl(fionread)返回0作为要读取的字节数 在T1时,调用recvfrom(bytes to read=0)。 有时,在t0和t1之间,实际数据用于在套接字接收队列中排队,并用于在调用recvfrom(bytes=0)时被丢弃。

    设置,rawmsgstoread=1的数目“解决”了这个问题。不过,我想这会影响我们的表现。它们的任何ioctl调用都可以将队列中的八位字节区分为0和有效负载为0的IP头

        2
  •  1
  •   Howard May    16 年前

    我有几个问题和一些事情要考虑。 1)您使用的是哪种SCTP实现,在哪种操作系统上。一些SCTP实现比其他实现更健壮。 2)SCTP是否对丢弃的数据包负确认?在Wireshark中搜索间隙确认。 3)你在哪里看到wireshark中丢失的数据包?你确定这些数据包没有重新传输吗? 4)Wireshark监控系统在哪里?如果它与应用程序不在同一条线上,那么它可能会看到应用程序没有看到的消息。 5)SCTP给出的具体指示是什么?

    如果您认为IP套接字Rx缓冲区溢出,那么可以考虑减小SCTP Rx窗口的大小;这通常在SCTP堆栈中可配置。RX窗口限制等待确认的未完成数据量,从而限制可能在IP缓冲区中的数据量。 您还可以尝试提高SCTP任务的优先级,以便它更快地从IP缓冲区中读取消息(这可能是最容易尝试的事情,在我看来是一件好事)。

    当做