3

所以我尝试了 boost::asio 并测试了阻塞回声示例。他们似乎并没有完全阻止它。至少不像我预期的那样。

是否有可能摆脱任何类型的缓冲或您可以拥有的最小缓冲区大小是多少?看起来 10000 字节太小了。

以下代码在阻塞之前运行了 2 次写入。如果我在写入中添加 boost::asio::transfer_exactly(10000) 参数,它仍然是 2. boost::asio::transfer_exactly(5000) 让我获得 5 次写入。

那么这个网络/io/asio 的东西是如何工作的呢?就像我只想发送一个字节并等待它到达另一端,而不需要任何额外的通信。

服务器:

boost::asio::io_service io_service;

tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), 12346));
tcp::socket sock(io_service);

a.accept(sock);
sock.non_blocking(false);
boost::asio::socket_base::send_buffer_size option(10000);
sock.set_option(option);

while(true) {
    char data[10000];

    boost::asio::socket_base::bytes_readable bytes_readable_cmd(true);
    sock.io_control(bytes_readable_cmd);
    std::size_t bytes_readable = bytes_readable_cmd.get();
    if(bytes_readable) {
        /**/
    }

    boost::asio::write(sock, boost::asio::buffer(data, 10000));
    printf("#\n");Sleep(10);
}

客户:

boost::asio::io_service io_service;

tcp::resolver resolver(io_service);
tcp::resolver::query query(tcp::v4(), "localhost", "12346");
tcp::resolver::iterator iterator = resolver.resolve(query);

tcp::socket sock(io_service);
boost::asio::connect(sock, iterator);
sock.non_blocking(false);
4

1 回答 1

5

我认为在这种情况下,write实际上只有在底层缓冲区已满时才会阻塞。

来自msdn的这句话在这里很合适:

发送功能的成功完成并不表示数据已成功交付和接收到接收者。该函数仅表示数据发送成功。

如果传输系统中没有可用的缓冲区空间来保存要传输的数据,则 send 将阻塞,除非套接字已置于非阻塞模式。

我尝试写入超过 64KB(完全从 65537 开始),它在第一次调用时被阻塞。

这不是 Asio 的工作方式,而是 TCP 和套接字的工作方式。这个答案也可能有帮助。

我想您需要从客户端显式发送收据确认,即推出您自己的应用层协议。

于 2012-05-11T10:24:37.677 回答