繁体   English   中英

增加 unix 域套接字的 boost::beast 包装器的消息缓冲区大小

[英]Increase message buffer size for boost::beast wrapper of unix domain socket

我正在使用 unix 域套接字的boost::beast包装器。 我的平台是 macOS。

首先,我定义套接字:

boost::asio::local::stream_protocol::socket socket;

我想用它来阅读最大 2k 的消息。

boost::asio::streambuf input_streambuf;
...
boost::asio::async_read(socket, input_streambuf,
                        boost::asio::transfer_at_least(1), yield);

然而,input_streambuf 只有 512 字节。

知道我是否可以从 Boost::beast 增加这个限制吗? 或者它可能是系统级别的一些定义?

谢谢

我在这里没有看到任何野兽类型。 这完全是 Asio 的。

此外, streambuf模拟DynamicBuffer概念。 它没有固定尺寸,因此您的说法不准确。

最后,无论streambuf的初始容量有多大,它都不会对你有多大好处,因为你将async_read指示为transfer_at_least(1) ,这意味着底层实现中的任何平台相关缓冲区都可能导致第一个read_some返回的数量要少得多。 例如,使用这个简单的服务器:

生活在 Coliru

#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <iostream>
namespace net = boost::asio;
using U = net::local::stream_protocol;

int main() {
    net::thread_pool io;
    using net::yield_context;

    U::acceptor acc(io, "./test.sock");
    acc.listen();
    U::socket s = acc.accept();

    spawn(io, [&](yield_context yield) { //
        net::streambuf buf;
        while (auto n = async_read(s, buf, net::transfer_at_least(1), yield))
            std::cout << "Read: " << n << " (cumulative: " << buf.size() << ")"
                      << std::endl;
    });

    io.join();
}

使用客户端时,例如:

netcat -U ./test.sock <<RESP
   Hello world
   This is Brussels calling
   From pool to pool
   RESP

将打印例如:

Read: 55 (cumulative: 55)

但是当以交互方式运行netcat -U./test.sock时:

Read: 12 (cumulative: 12)
Read: 30 (cumulative: 42)
Read: 17 (cumulative: 59)

事实上,我们可以毫不夸张地向它扔上千本词典:

for a in {1..1000}; do cat /etc/dictionaries-common/words; done | netcat -U ./test.sock

output 是:

Read: 512 (cumulative: 512)
Read: 512 (cumulative: 1024)
Read: 512 (cumulative: 1536)
Read: 512 (cumulative: 2048)
Read: 512 (cumulative: 2560)
Read: 1536 (cumulative: 4096)
Read: 512 (cumulative: 4608)
Read: 3584 (cumulative: 8192)
Read: 512 (cumulative: 8704)
Read: 7680 (cumulative: 16384)
Read: 512 (cumulative: 16896)
Read: 15872 (cumulative: 32768)
Read: 512 (cumulative: 33280)
Read: 32256 (cumulative: 65536)
Read: 512 (cumulative: 66048)
Read: 65024 (cumulative: 131072)
Read: 512 (cumulative: 131584)
Read: 65536 (cumulative: 197120)
...
Read: 49152 (cumulative: 971409238)
Read: 49152 (cumulative: 971458390)
Read: 49152 (cumulative: 971507542)
Read: 49152 (cumulative: 971556694)
Read: 21306 (cumulative: 971578000)
terminate called after throwing an instance of 'boost::wrapexcept<boost::exception_detail::current_exception_std_exception_wrapper<std::runtime_error> >'
  what():  End of file [asio.misc:2]

如您所见,缓冲区的大小取决于操作系统,操作系统实际上可以很好地按要求扩展缓冲区。

改进指令

因此,不要使用transfer_at_least ,而是使用您认为合理的任何最小值:

while (auto n = async_read(s, buf, net::transfer_at_least(1024*1024), yield))
    std::cout << "Read: " << n << " (cumulative: " << buf.size() << ")"
              << std::endl;

改为打印:

Read: 1048576 (cumulative: 1048576)
Read: 1048576 (cumulative: 2097152)
Read: 1063342 (cumulative: 3160494)
Read: 1086266 (cumulative: 4246760)
...
Read: 1086266 (cumulative: 969962524)
Read: 1102650 (cumulative: 971065174)

或者,如果您满足于阅读直到 EOF:

while (auto n = async_read(s, buf, yield[ec])) {
    std::cout << ec.message() << ": " << n
              << " (cumulative: " << buf.size() << ")" << std::endl;
    if (ec.failed())
        break;
}

请注意,我们巧妙地添加了 error_code 检查,因此我们不会因 EOF 而错过整个传输。 现在打印:

End of file: 971578000 (cumulative: 971578000)

最后,您可能想要限制最大容量,比如 50 Mib:

constexpr size_t _50MiB = 50<<20;
net::streambuf buf(_50MiB);

boost::system::error_code ec;
while (auto n = async_read(s, buf, yield[ec])) {
    std::cout << ec.message() << ": " << n
              << " (cumulative: " << buf.size() << ")" << std::endl;
    if (ec.failed())
        break;
}
if (ec != net::error::eof && buf.size() == _50MiB) {
    std::cout << "Warning: message truncated" << std::endl;
}

现在我们不能强迫 feed 字典耗尽 memory:

Success: 52428800 (cumulative: 52428800)
Warning: message truncated

暂无
暂无

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

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