开发者

Downloader doesnt get all the data

So i am trying to make a downloader based on http protocol. It works ok on small txt files, but if i try downloading something bigger, lets say a picture, it doesnt get all of the data.

void accel::getfile(int from, int to){
    //send GET message
    string msg = msg_get(fpath, true, from, to);
    int back = send(socketC, (char*)&msg[0], msg.size(), 0);

    //recv response
    int buffsize = 512;     //buffer size. should not be less than 512
    string buff(buffsize, 0);//, resp;  //buffer, response message
    fstream output(fname, ios::out, ios::trunc);    //file
    bool found = false;
    int dld = 0;

    do {
        //recv msg to buffer
        back = recv(socketC, (char*)&buff[0], buffsize, 0);
        dld += back;
        //buff.insert(back, "\0");
        //cout << buff.c_str();
        //is the writing of the body started?
        if (found){
            output.write(buff.c_str(), back);
            cout << ".";
        }
        //if not find where the body starts
        else {
            int point = buff.find("\r\n\r\n");
            if (point != -1){
                char *p = (char*)&开发者_运维问答;buff[point+4];
                output.write(p, back-point-4);
                cout << ".";
                found = true;
            }
        }
    } while (back == buffsize);

    output.close();

    cout << "\nComplete\n";
    cout << dld << "bytes downloaded\n";
}

Requests:

string msg_head(string fpath, bool keep_alive){
    string msg;
    //
    msg = "HEAD ";
    msg += fpath;
    msg += " HTTP/1.0\r\n";

    if (keep_alive)
        msg += "Connection: keep-alive\r\n\r\n";
    else
        msg += "Connection: close\r\n\r\n";

    return msg;
}

string msg_get(string fpath, bool keep_alive, int from, int to){
    string msg;
    char number[10];

    msg = "GET ";
    msg += fpath;
    msg += " HTTP/1.0\r\n";

    msg += "Range: bytes=";
    sprintf(number, "%d", from);
    msg += number;
    msg += "-";
    sprintf(number, "%d", to);
    msg += number;
    msg += "\r\n";

    if (keep_alive)
        msg += "Connection: keep-alive\r\n\r\n";
    else
        msg += "Connection: close\r\n\r\n";

    return msg;
}


recv may not fill the whole buffer if there is not enough data available yet. You should detect the end of the message by one of the means specified in the HTTP protocol.


Your code appears to assume that recv always returns the maximum amount of data (ie. that it waits for n bytes to appear). recv may return early if a smaller amount of data is currently available.

Instead, you should continue until either disconnection (when recv returns 0, or an error such as WSAECONNRESET) or an expected number of bytes (which you should have once the header is fully received)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜