C++ 网络套接字、SCTP 和数据包大小

标签 c++ sockets networking packet sctp

我目前正在开发一个使用面向连接的 SCTP 的服务器来为少量客户端提供服务。在完成第一个带有简单实现的原型(prototype)之后,我现在正在分析要优化的应用程序。事实证明,CPU 时间的两个主要消耗者之一是网络部分。

我实现的应用层协议(protocol)的效率有两个问题:

1) 数据包大小

目前,我使用的最大数据包大小为 64 字节。您可以找到许多讨论过大的数据包大小的帖子,但是它们可以太小吗?由于 SCTP 允许我一次读取一个数据包 - 类似于 UPD - 同时保证按顺序交付 - 类似于 TCP - 这种显着简化的实现。但是,如果我理解正确的话,每次我发送一个数据包都会花费一个系统调用。系统调用的数量是否对性能有重大影响?我能否通过以更大的数据包(即 1024 - 8192 字节)成束发送消息来减少大量 CPU 周期?

2) 读写缓冲区

我目前正在使用 memcpy 将数据移入和移出应用程序级网络缓冲区。我发现许多关于什么更有效、memcpy 或正常分配的相互矛盾的帖子。我想知道在这种情况下,一种方法是否会比另一种方法快得多:

选项 1

void Network::ReceivePacket(char* packet)
{
    uint8_t param1;
    uint16_t param2
    uint32_t param3;

    memcpy(&param1, packet, 1);
    memcpy(&param2, packet+1, 2);
    memcpy(&param3, packet+3, 4);

    // Handle the packet here
}

void Network::SendPacket(uint8_t param1, uint16_t param2, uint32_t param3)
{
    char packet[7]

    memcpy(&packet, &param1, 1);
    memcpy(&packet+1, &param2, 2);
    memcpy(&packet+3, &param3, 4);

    // Send the packet here
}

选项 2

void Network::ReceivePacket(char* packet)
{
    uint8_t param1;
    uint16_t param2
    uint32_t param3;

    param1 = *((uint8_t*)packet);
    param2 = *((uint16_t*)packet+1);
    param3 = *((uint32_t*)packet+3);

    // Handle the packet here
}

void Network::SendPacket(uint8_t param1, uint16_t param2, uint32_t param3)
{
    char packet[7]

    *((uint8_t*)packet) = param1;
    *((uint16_t*)packet+1) = param2;
    *((uint32_t*)packet+3) = param3;

    // Send the packet here
}

第一个对我来说似乎更干净,但我发现很多帖子表明第二个可能更快一些。

当然欢迎任何类型的反馈。

最佳答案

据我所知,编译器会特别优化 memcpy 调用,因此您可能应该使用它。

关于你的第一个问题:

  • 总结:使数据包大小尽可能大,避免 CPU 性能降低的可能性。

A syscall,一个系统调用,是你的操作系统回复或处理你的请求,每次你的请求都在内核中执行,这是一个适度的工作量。 老实说,我不熟悉 SCTP 概念,事实上,自从上次处理一些东西并通过 TCP 创建服务器以来,我就没有处理过套接字编程。我记得相关物理层元素的 MTU 是 1500,我还记得将我的数据包大小实现为 1450-1460,因为我试图获得下面的最大数据包大小1500 上限。

所以我要说的是,如果我是你,我希望我的操作系统尽可能不活跃,这样我就不会在 CPU 性能方面遇到任何问题。

关于C++ 网络套接字、SCTP 和数据包大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18441769/

相关文章:

c++ - 计算可变参数模板元组中的 std::optional 类型

C++11 虚拟析构函数和 move 特殊函数的自动生成

python - python 套接字中的无效端口

networking - 在端口和套接字之间混淆

networking - 我们可以手动限制网络接口(interface)的带宽吗?

c++ - std::map::size() 不同于迭代器

android - Android WebView 中的套接字

linux - 接受 pthread 内的连接

networking - 在游戏中使用多个端口有什么好处?

c++ - ‘(’ 标记之前的意外主表达式