Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

read: End of file in ASIO. Why is socket getting closed?

Tags:

c++

boost-asio

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.

like image 314
v010dya Avatar asked Sep 27 '22 03:09

v010dya


1 Answers

Just handle the error condition: http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/reference/read/overload2.html

asio::streambuf response;
boost::system::error_code ec;
size_t s = asio::read(socket, response, ec); // no condition, so read till EOF

if (!ec || ec == boost::asio::error::eof) {
    // woot, no problem
}
like image 140
sehe Avatar answered Sep 30 '22 06:09

sehe