I have the example(*) code like this:
std::string protocol = "http";
std::string server = "www.example.com";
std::string path = "/";
asio::io_service service;
asio::ip::tcp::resolver resolver(service);
asio::ip::tcp::resolver::query query(server, protocol);
asio::ip::tcp::socket socket(service);
asio::ip::tcp::resolver::iterator end;
auto it = resolver.resolve(query);
asio::error_code error;
socket.connect(*it, error);
while(error && ++it!=end)
{
socket.close();
socket.connect(*it, error);
}
asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << path << " HTTP/1.0\r\n";
request_stream << "Host: " << server << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
asio::streambuf response;
size_t s = asio::read(socket, response);
When asio::read
is called i get:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::system_error> >'
what(): read: End of file
As i understand it, this error happens because the socket is getting closed while trying to read. But i do not understand why is it getting closed.
I have originally had read_until
there, and it had the same error.
Am i doing something wrong with initiation of the connection or is it getting terminated for some other reason?
(*) Example means, that it is an example, and not a complete working program. If the example can be made shorter or better, please feel free to edit the question.
Per sehe's answer i have attempted the following:
size_t s = asio::read(socket, response, error);
if(!error || error==asio::error::eof)
{
if(s==0)
{
std::cerr << "Same problem" << std::endl;
}
}
The result is that "Same problem" is displayed when running the program, which means that it gets EOF before reading any data.
Per YSC's answer i have tried the following:
for (;;)
{
char buf[255];
size_t len = socket.read_some(asio::buffer(buf, 255), error);
if (error == asio::error::eof)
{
std::cout << std::endl << "Connection closed" << std::endl;
break; // Connection closed cleanly by peer.
}
else if (error)
{
std::cerr << "Error" << std::endl;
return 1;
}
std::cout.write(buf, len);
}
No data appears, and "Connection closed" is shown after a slight delay. Which means that i get EOF without any data with that approach as well.
read()
, not before or after. Which means you would have to surround that statement with a try/catch. However, from my experience, ASIO is not done for the type of access you are trying to do there. I may be wrong, but it is well adapted for things using more permanent connections rather than a one query and one answer. With a NONBLOCK socket, you cannot be sure that the client will read everything written by the server. That's because the client may shutdown the socket and that flushes any data left over! – Tude