2011-01-20 6 views
1

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

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

ответ

0

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

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

0

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

Смежные вопросы