简体   繁体   English

关于boost :: asio套接字和阻塞

[英]About boost::asio sockets and blocking

So I was trying out boost::asio and tested the blocking echo examples. 所以我尝试了boost :: asio并测试了阻塞回声示例。 They don't seem to be fully blocking it seems. 它们似乎似乎没有完全阻止它。 Not at least in the way I expected. 至少不是我预期的方式。

Is it possible to get rid of any kind of buffering or what's the smallest buffer size you can have? 是否可以摆脱任何类型的缓冲或什么是最小的缓冲区大小? It looks like 10000 bytes is too small. 看起来10000字节太小了。

The following code runs through 2 writes before it blocks. 以下代码在阻塞之前运行2次写入。 If I add boost::asio::transfer_exactly(10000) argument to the write, it's still 2. boost::asio::transfer_exactly(5000) gets me 5 writes. 如果我将boost :: asio :: transfer_exactly(10000)参数添加到写入,它仍然是2. boost :: asio :: transfer_exactly(5000)让我写入5次。

So how does this networking/io/asio stuff work? 那么这个网络/ io / asio的工作原理是什么? Like if I wanted to send just a single byte and wait for it to reach the other end, without any additional communication. 就像我只想发送一个字节并等待它到达另一端,没有任何额外的通信。

Server: 服务器:

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);
}

Client: 客户:

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);

I think in this case write actually blocks only when underlying buffer is full. 我认为在这种情况下,只有在底层缓冲区已满时才write实际块。

This quote from msdn would be appropriate here: msdn的引用适用于此:

The successful completion of a send function does not indicate that the data was successfully delivered and received to the recipient. 成功完成发送功能并不表示数据已成功发送并接收到收件人。 This function only indicates the data was successfully sent. 此功能仅表示数据已成功发送。

If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in nonblocking mode. 如果传输系统中没有可用的缓冲区空间来保存要传输的数据,则发送将阻止,除非套接字已置于非阻塞模式。

I tried writing more than 64KB (starting exactly with 65537) and it blocked on the first call. 我尝试写入超过64KB(完全以65537开始)并在第一次调用时阻止。

This is not how Asio works, but how TCP and sockets work. 这不是Asio的工作方式,而是TCP和套接字的工作原理。 This answer may be of help too. 这个答案也可能有所帮助。

I guess you need to explicitly send receipt confirmation from client, ie roll your own application layer protocol. 我想你需要明确地从客户端发送收据确认,即滚动你自己的应用层协议。

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

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