Ivarpoiss
Ivarpoiss

Reputation: 1035

About boost::asio sockets and blocking

So I was trying out boost::asio and tested the blocking echo examples. 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.

The following code runs through 2 writes before it blocks. 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.

So how does this networking/io/asio stuff work? 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);

Upvotes: 3

Views: 8151

Answers (1)

Vsevolod Golovanov
Vsevolod Golovanov

Reputation: 4206

I think in this case write actually blocks only when underlying buffer is full.

This quote from msdn would be appropriate here:

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.

This is not how Asio works, but how TCP and sockets work. This answer may be of help too.

I guess you need to explicitly send receipt confirmation from client, i.e. roll your own application layer protocol.

Upvotes: 5

Related Questions