简体   繁体   English

如果需要数据包标头,通过 UDP 发送大型连续缓冲区的最有效方法是什么?

[英]Most efficient way to send large continuous buffer over UDP if packet headers are required?

I'm trying to find the most efficient way to stream large amounts of data out of a UDP socket.我正在尝试找到从 UDP 套接字流式传输大量数据的最有效方法。 Using a double (or triple) buffering approach in which one thread fills a large buffer with data and then another thread takes ownership of the buffer and streams it out via a socket seems more efficient than sending the sender thread small packet sized chunks.使用双(或三)缓冲方法,其中一个线程用数据填充大缓冲区,然后另一个线程获取缓冲区的所有权并通过套接字将其流式传输,这似乎比向发送者线程发送小数据包大小的块更有效。

However, the protocol I'm using requires that protocol-specific headers be added to each chunk of data before sending.但是,我使用的协议要求在发送之前将特定于协议的标头添加到每个数据块中。 The header must be at the beginning of each packet.标头必须位于每个数据包的开头。

The best way I've thought to accomplish this so far would require memcopying every byte of data out of the large buffer before sending, similar to the code below:到目前为止,我认为实现这一点的最佳方法是在发送之前将每个字节的数据从大缓冲区中复制出来,类似于下面的代码:

void UdpSender::udp_send()
{
    /**
     * A large buffer, simulating a ping-pong buffer filled in a separate thread
     */
    const size_t BUFFER_SIZE = 1024*1024*2;
    uint8_t send_buffer[BUFFER_SIZE];
    std::memset(send_buffer, 'a', BUFFER_SIZE);


    const uint16_t MAX_PACKET_PAYLOAD_SIZE = 1400;

    struct Packet
    {
        uint32_t header_value1;
        uint32_t header_value2;
        uint8_t payload[MAX_PACKET_PAYLOAD_SIZE];
    };

    //Offset into the large buffer
    uint8_t send_buffer_offset = 0;

    Packet packet;
    packet.header_value1 = 1;
    packet.header_value2 = 2;
    //Requires copying everything out of the buffer before sending
    std::memcpy(&packet.payload, &send_buffer+send_buffer_offset, MAX_PACKET_PAYLOAD_SIZE);

    sendto(active_socket_fd, &packet, sizeof(packet), 0, p_dest_addr, dest_addr_size);
}

The data I need to send is already in a contiguous buffer that would be efficient to send (requiring no additional memcopys) if I didn't have to add a header to each chunk of data being sent out.我需要发送的数据已经在一个连续的缓冲区中,如果我不必为每个要发送的数据块添加标头,则可以有效地发送(不需要额外的内存副本)。 Is there any better way I could approach this problem that would avoid memcopying the entire buffer?有没有更好的方法可以解决这个问题,以避免复制整个缓冲区?

Thanks!谢谢!

Most implementations of UDP (at least the standard ones) unfortunately do not support scatter/gather.遗憾的是,大多数 UDP 实现(至少是标准实现)不支持分散/聚集。 But .. I've done some tests and copying a K or so of ram memory to ram memory is not as expensive as I thought, especially if you use built in functions instead of for loop.但是..我已经做了一些测试,将 K 左右的 ram 内存复制到 ram 内存并没有我想象的那么昂贵,特别是如果你使用内置函数而不是 for 循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM