I am using boost::asio to make a synchronous TCP socket connection to a node.js TCP server application that runs on the same computer. I am using Embarcadero RAD studio XE4 on Windows building 64 bit application that uses the Embarcadero integrated boost version 1.50.
Things work fine except when the node.js TCP server shuts down. When this occurs my C++ client application does not detect the disconnection when I read from the socket. However, it does detect the disconnection when I write to the socket.
My current code was written after trying to make sense of the boost documentation and a variety of answers here on SO. The reading portion of the code is as follows (I have omitted the checking of the error code for compactness)
boost::system::error_code ec;
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket s(io_service);
boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"),m_port);
ec = s.connect(ep,ec);
std::size_t bytes_available = s.available(ec);
std::vector<unsigned char> data(bytes_available,0);
size_t read_len = boost::asio::read(s, boost::asio::buffer(data),boost::asio::transfer_at_least(bytes_available),ec);
if ((boost::asio::error::eof == ec) || (boost::asio::error::connection_reset == ec))
{
// disconnection
break;
}
This is not a great system as it is running in its own thread inside a loop and polling for data constantly until the program is shutdown. Normally I would not perform a read() on a socket when there is no data there but I do it in this case since all documentation leads me to believe that the socket disconnection is detected only when performing a read or write to the socket. The problem is that the above code is simply never detecting the disconnection when the node.js application shuts down. If I am writing I detect it (the write part of the code is using the same boost::asio::error` errors as the read for detection) but not when reading.
Obviously I cannot perform a read for byte amounts larger than that are available or my thread will block and I will be unable to perform writes later on in my thread loop.
Am I missing another specific boost error code to detect the error condition? Or is it a problem specifically with the zero length read. If that is the case are there any other options available to me?
Currently I am getting the node.js server to write out a specific message when it to the socket when it shuts down which I am detecting and then closing the client end myself. However, this is a bit of a hack and I would prefer a clean way to detect the disconnect if possible.