0xDEAD BEEF
0xDEAD BEEF

Reputation: 2104

boost asio async_write not generating broken pipe or other error on disconnected client

situation is following - server is sending data to clients, however some clients are disconnected (not gracefully).

Yet write handler always completes without any error about broken pipe. This is TCP/IP connection so I assume that there should be some error after some while if sender (server) no longer receives ACK packets from client.

How do I handle this error?

    auto writeHandler = boost::bind(&ChatConnection::OnWrite, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred);
    boost::asio::async_write(socket_, write_queue_.front()->Buffer(), writeHandler);

writeHandler is always called with success.

Upvotes: 3

Views: 957

Answers (1)

sehe
sehe

Reputation: 392833

I've created the simplest server I could think of (which just accepts a single TCP connection on port 6767 and dumps 4k blocks of /dev/urandom into it until failure):

#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <iostream>
#include <fstream>

int main() {
    using namespace boost::asio; // being really lazy here
    using ip::tcp;
    boost::system::error_code ec;

    io_service svc;
    tcp::acceptor acc {svc, tcp::v4()};
    acc.bind({tcp::v4(), 6767});
    acc.listen(1);

    tcp::socket s{svc};
    if (!acc.accept(s, ec)) {
        spawn(svc, [&](yield_context yc) { 

            std::ifstream ifs("/dev/urandom", std::ios::binary);
            char buf[4<<10];

            while (ifs.read(buf, sizeof(buf))) {
                boost::asio::async_write(s, buffer(buf), yc[ec]);
                std::cout << ec.message() << "\n";
                if (ec) break;
            }
        });
    }

    svc.run(); // :) sometimes helps...
    std::cout << "Bye\n";
}

Build & run with e.g.

g++ -std=c++11 -O2 -Wall -pedantic -pthread main.cpp -lboost_{system,thread,context,coroutine} -o test
./test |& uniq -c&
nc 127.0.0.1 6767 > /dev/null <<< "test client"

This shows:

$ ./test |& uniq -c&
[1] 15362
$ nc localhost 6767 > /dev/null <<<"test"
^C
$    7101 Success
      1 Broken pipe
      1 Bye

[1]+  Done                    ./test 2>&1 | uniq -c

Perhaps you should show us your reduced sample (http://sscce.org) or you can see what you differently from my example.

Upvotes: 3

Related Questions