Загрузчик не получает все данные - PullRequest
1 голос
/ 20 января 2011

Так что я пытаюсь сделать загрузчик на основе протокола HTTP.Он работает нормально для небольших текстовых файлов, но если я пытаюсь загрузить что-то большее, скажем, изображение, он не получает все данные.

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";
}

Запросы:

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;
}

Ответы [ 2 ]

0 голосов
/ 20 января 2011

recv может не заполнить весь буфер, если данных еще недостаточно.Вы должны обнаружить конец сообщения одним из способов, указанных в протоколе HTTP .

0 голосов
/ 20 января 2011

Ваш код, по-видимому, предполагает, что recv всегда возвращает максимальный объем данных (т. Е. Он ожидает появления n байтов). recv может вернуться рано, если в настоящее время доступно меньшее количество данных.

Вместо этого следует продолжать до тех пор, пока не произойдет отключение (когда recv вернет 0, или ошибка, такая как WSAECONNRESET) или ожидаемое количество байтов (которое вы должны иметь после полного получения заголовка)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...