S&? 2024-09-24 15:59 采纳率: 0%
浏览 3

ikcp配合udp通信速率与稳定性的问题

在使用ikcp配合UVW库中的udp通信时,想让通信速度达到千兆的同时可以在网络不稳定时仍可以正确传输文件,但是发现在将kcp的mtu设置为1400时即使

ikcp_nodelay(kcp, 1, 1, 2, 1);
ikcp_wndsize(kcp, 1200, 1200);
const size_t buff_size = 15000;

这样设置速度也只能达到70MB/S左右(这是在不调mtu的情B况下尝试出来的最大速度,调用update的频率为1毫秒一次)
但是当把发送端的mtu设置到2800时(ikcp_setmtu(kcp, 2800);)速度就可以达到110MB/s,但是好像是因为ip分片的原因,在网络丢包率有2%的时候,传输就会卡到不可用的状态。不知道还有没有什么别的办法可以同时满足速度和稳定性。(也不能开启巨型帧)
整体代码如下(发送端):

int kcp_output(const char *buf, int len, ikcpcb *kcp, void *user) {
    char* send_data = const_cast<char*>(buf);
    auto udp_send = static_cast<uvw::udp_handle*>(user);
    int send_res = udp_send->send("192.168.0.128", 12344, send_data, len);
    if(send_res < 0) {
        std::cout << "send falid" << std::endl;
    }
    return send_res;
}
void readfile(ikcpcb *kcp, std::string filePath, int buff_size) {
    std::ifstream file(filePath, std::ios::binary);
    if (!file.is_open()) {
        std::cerr << "Failed to open file: " << filePath << std::endl;
        return;
    }
    std::cout << "File Reading..." << std::endl;
    std::vector<char> buffer(buff_size);

    size_t pos = filePath.find_last_of("/\\");
    std::string Name = filePath.substr(pos + 1);
    ikcp_send(kcp, &Name[0], static_cast<int>(Name.length()));

    while (file.read(buffer.data(), buffer.size())) {
        ikcp_send(kcp, buffer.data(), static_cast<int>(file.gcount()));
    }
    if (file.gcount() > 0) {
        ikcp_send(kcp, buffer.data(), static_cast<int>(file.gcount()));
    }
    
}

void start() {
    std::cout << "Enter the file path and file name:" << std::endl;
    std::string filePath = "d:/ikcptest.zip";
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "WSAStartup failed\n";
        return;
    }
    auto loop = uvw::loop::get_default();
    auto udp_send = loop->resource<uvw::udp_handle>();
    int bindres = udp_send->bind("192.168.0.22", INADDR_ANY);
    if(bindres < 0) {
        std::cout << "send bind falid" << std::endl;
    }
    ikcpcb *kcp = ikcp_create(0x11223344, static_cast<void*>(udp_send.get()));
    ikcp_setoutput(kcp, kcp_output);
    ikcp_nodelay(kcp, 1, 1, 2, 1);
    ikcp_wndsize(kcp, 1200, 1200);
    const size_t buff_size = 15000;

    auto udp_recv = loop->resource<uvw::udp_handle>();
    int res = udp_recv->bind("192.168.0.22", 12355);
    char kcp_buf[1024];
    udp_recv->on<uvw::udp_data_event>([&](const uvw::udp_data_event &event, uvw::udp_handle &handle) {
        memset(kcp_buf, 0, sizeof(kcp_buf));
        int ret = ikcp_input(kcp, event.data.get(), event.length);
        int res = ikcp_recv(kcp, kcp_buf, sizeof(kcp_buf));
        udp_recv->recv();
    });
    udp_recv->recv();
    auto timer = loop->resource<uvw::timer_handle>();
    std::chrono::milliseconds timeout(0);
    std::chrono::milliseconds repeat(1);
    timer->on<uvw::timer_event>([&](const uvw::timer_event&, uvw::timer_handle&){
        ikcp_update(kcp, GetTickCount());
    });
    timer->start(timeout, repeat);
    std::thread(readfile, kcp, filePath, buff_size).detach();
    loop->run();
    WSACleanup();
}

int main(int argc, char *argv[])
{
    start();
    return 0;
}
  • 写回答

1条回答 默认 最新

  • 软件技术NINI 2024-09-24 16:22
    关注

    在使用ikcp(一种基于UDP的快速可靠传输协议)配合UDP进行通信时,确实会面临通信速率与稳定性方面的问题。以下是对这些问题的详细分析和建议:

    一、通信速率问题
    MTU设置:
    MTU(最大传输单元)是影响UDP通信速率的关键因素之一。在UDP通信中,数据包的大小受限于MTU。当数据包大小超过MTU时,IP层会对其进行分片,这可能会降低传输效率并增加丢包的风险。
    增大MTU可以提高通信速率,但过大的MTU在网络环境不稳定时可能导致更高的丢包率。因此,需要根据实际网络环境调整MTU大小。
    在使用ikcp时,可以通过ikcp_setmtu函数设置MTU值。
    ikcp配置:
    nodelay模式:启用nodelay模式可以减少延迟,但可能会牺牲一定的带宽利用率。通过ikcp_nodelay函数可以设置nodelay模式及其相关参数(如interval、resend、nc)。
    窗口大小:窗口大小决定了发送方在收到确认之前可以发送的数据量。通过ikcp_wndsize函数可以设置窗口大小,以平衡传输速度和内存使用。
    数据包处理频率:
    ikcp_update函数的调用频率也会影响通信速率。通常,更高的调用频率可以提供更准确的RTT(往返时间)估计和更快的重传机制,但也会增加CPU负担。
    二、稳定性问题
    丢包处理:
    UDP本身不提供重传机制,但ikcp通过用户层实现了可靠性传输。在丢包率较高时,ikcp的重传机制可能无法及时恢复数据,导致传输不稳定。
    可以通过调整ikcp的重传参数(如快速重传模式)来提高在丢包情况下的恢复能力。
    拥塞控制:
    UDP没有内置的拥塞控制机制,这可能导致在网络拥塞时数据包大量丢失。虽然ikcp在一定程度上可以缓解这个问题,但在极端情况下仍可能受到影响。
    可以考虑在应用层实现简单的拥塞控制策略,如根据网络状况动态调整发送速率。
    网络监控与调优:
    定期进行网络监控,了解网络状况的变化,并根据需要进行调优。例如,调整MTU值、重传参数等。
    三、建议
    实验与测试:
    在不同的网络环境下进行大量的实验和测试,以找到最适合当前网络环境的MTU值和ikcp配置参数。
    监控通信过程中的丢包率、延迟等关键指标,以便及时调整参数。
    优化代码:
    确保ikcp和UDP相关代码的实现高效且稳定。
    使用高效的数据结构和算法来减少CPU和内存的使用。
    备份方案:
    在对实时性和可靠性要求极高的应用中,可以考虑使用TCP或其他更可靠的传输协议作为备份方案。
    综上所述,通过合理设置MTU、调整ikcp配置参数、优化代码以及实施网络监控与调优等措施,可以在一定程度上提高ikcp配合UDP通信的速率和稳定性。然而,由于网络环境的复杂性和多变性,这些措施可能需要根据实际情况进行不断调整和优化。

    评论

报告相同问题?

问题事件

  • 修改了问题 9月24日
  • 修改了问题 9月24日
  • 创建了问题 9月24日

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?