2015-02-03 4 views
0

я создаю простой клиент HTTP для загрузки конкретного файла из Интернета, я получил проблему, когда я читаю данные, вот мой цикл:чтение ответа HTTP

do{ 
     client.readString(aux, 256); 
     req.append(aux); 
    }while(client.canRead()); 

клиент является TCPClient объект, это прекрасно, метод canRead использовать select() для проверки наличия доступных данных, я думаю, что программа быстро считывает данные, что иногда canRead вызывается перед новым доходом данных и возвращает false, поэтому я не читаю все ответ, чтобы доказать, что я говорю, я использую этот код:

AGAIN: 
    do{ 
     client.readString(aux, 256); 
     req.append(aux); 
    }while((test = client.canRead())); 

    if(!test){ 
     std::cout << "false\n"; 
     std::cout << req << std::endl << std::endl; 
     system("pause>null"); 
     goto AGAIN; 
    } 

так w и я вернусь к AGAIN, есть больше данных для чтения, я знаю, что метод canRead работает нормально, проблема в том, что я не знаю, когда прекратить чтение данных, и зависеть от этого метода явно не рекомендуется. Чтобы решить эту проблему, я вижу только два решения: поместите некоторые задержки (Сон) на код или обработайте данные непосредственно из файла сокета, но прежде чем я попытаюсь это сделать, я пришел сюда, чтобы искать лучшие решения, есть ли официальный способ сделать это ? если кто-нибудь может мне помочь, я буду благодарен вам.

+2

Вам нужно выяснить из заголовков http, сколько данных вам нужно будет прочитать. Это единственный надежный способ сделать это. – Mat

+0

«Я знаю, что метод canRead работает нормально» - держу пари, что нет. из вашего описания это звучит как его неблокирование, но тогда ваша логика приложения неверна. –

+0

Вам нужно полностью выбрать 'select' из этого цикла. Прочитайте спецификацию HTTP. – davmac

ответ

0

Проблема решена, используя метод для подглядывания данных, я просматриваю данные, пока не найду первый «\ r \ n \ r \ n», который указывает конец заголовка ответа, после чего я получаю размер до этого '\ r \ n \ r \ n' и прочитайте этот объем данных из сокета, поэтому я обрабатываю заголовок: посмотрите, есть ли длина содержимого или передача-кодировка (прямо сейчас я только поддерживаю chunked, потому что это единственное тот, который требуется моей программе), и вызывать специальный метод для «декодирования» тела ответа. Таким образом, код:

do{ 
     //if the header never ends.... 
     if(req.size() > MAX_HEADER_SIZE) 
      throw std::runtime_error("Invalid HTTP header."); 

     req = peekAvailable(client); 
    }while((header_end = req.find("\r\n\r\n")) == std::string::npos); 

    client.readString(req, header_end + 4); 
    //... Here comes the part to interpret the header information... 

И peekAvailable метод:

std::string peekAvailable(TCPClient& client){ 
    uint32 available_data; 
    std::string data; 

    while((available_data = client.getAvailableData()) == 0){ 
     //Here implement a timeout counter.... 
     Sleep(1); 
    } 

    client.peekString(data, available_data); 

    return data; 
    } 

Спасибо всем за внимание.

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