Home:ALL Converter>Boost socket not throwing EOF on disconnection

Boost socket not throwing EOF on disconnection

Ask Time:2014-01-28T15:29:29         Author:Farrukh Arshad

Json Formatter

I am writing a simple download service for one of my project in C++ using Boost libraries. What I want is while downloading if my connection breaks, I should stop download. I have read different places that when connection is broken socket returns EOF error, Boost sockets does the same. But my problem is, when the connection is broken boost socket does not throw EOF, instead it just keep on connected, and once connection is back it resumes the download where it stopped. I don't want to resume, I want to quit, so that I will do my own resuming. Question is when the connection is broken why boost socket is not throwing EOF error. Following is my sample code. I have also tried it with asynchronous implementation, I have also tried it with socket.read_some function but same behavior.

std::string responseString = "";

try {
    // === Send HTTP Request to get Proxy End Point
    std::string apiPath = "/qtproject/archive/qt/4.0/" + filename;
    boost::asio::io_service io_service;

    // Get a list of endpoints corrosponding to the server name
    tcp::resolver resolver(io_service);
    tcp::resolver::query query(serverip, serverport);
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);

    // Try each endpoint untill we successfully establish a connection.
    tcp::socket socket(io_service);
    boost::asio::connect(socket, endpoint_iterator);

    boost::system::error_code error = boost::asio::error::host_not_found;
    boost::asio::streambuf request;
    std::ostream request_stream(&request);
    request_stream << "GET " << apiPath << " HTTP/1.0\r\n";
    request_stream << "Host: " << serverip << "\r\n";
    request_stream << "Accept: */*\r\n";
    request_stream << "Connection: close\r\n\r\n";

    // Send the request
    boost::asio::write(socket, request);

    // === Read Server Response
    boost::asio::streambuf response;
    boost::asio::read_until(socket, response, "\r\n");

    // Check that response is OK.
    std::istream response_stream(&response);
    std::string http_version;
    response_stream >> http_version;
    unsigned int status_code;
    response_stream >> status_code;
    std::string status_message;
    std::getline(response_stream, status_message);
    if (!response_stream || http_version.substr(0, 5) != "HTTP/") {
        std::cout << " Bad Server Response " << std::endl;
    }
    if (status_code != 200) {
        std::cout << "Bad Status Code = " << status_code << std::endl;
    }
    // Read the response headers, which are terminated by a blank line.
    //boost::asio::read_until(socket, response, "\r\n\r\n");
    //boost::system::error_code error; //boost::asio::buffer(data, sizeof data)
    unsigned char data[1024];
    socket.read_some(boost::asio::buffer(data, sizeof(data)), error);

    // Process the response headers.
    std::string header;
    while (std::getline(response_stream, header) && header != "\r");

    ofstream image;
    std::string filepath = "/home/farshad/TBD/" + filename;
    image.open(filepath.c_str());

    // Read until EOF, writing data to output as we go.
    int downloadedSize = 0;
    int readSize = 0;
    while ( (readSize = socket.read_some(boost::asio::buffer(data, sizeof(data)), error)) )
    {
            // When the connection is broken it keeps in this while loop, 
            // where I am expecting it to throw EOF error. Once connection is back, 
            // it resumes from the same while loop.
        downloadedSize += readSize;
        std::cout << "Data Read = " << downloadedSize <<  " Bytes\n";
        //memset(data, 0x0, sizeof(data));
        //image << &response;
        //std::cout << "Downloaded = " << (downloadedSize) << " Bytes\n";
    }

    //std::cout << "File Size = " << image.gcount() << std::endl;
    image.close();
    if (error != boost::asio::error::eof)
      throw boost::system::system_error(error);
    else if ( error == boost::asio::error::eof  ) {
        std::cout << "End of file approached";
        throw boost::system::system_error(error);
    }
}
catch ( std::exception& e)
{
    std::cout << "Exception: " << e.what() << std::endl;
}
catch ( ... )
{
    std::cout << "HURRAY: We got error" << std::endl;
}

UPDATE The disconnection is of nature that someone pulls out the cable, or internet connection disconnection due to ISP.

Author:Farrukh Arshad,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/21399385/boost-socket-not-throwing-eof-on-disconnection
yy