2015-11-16 2 views
-1

Вот метод, в котором находится цикл while. Я просто подключился к серверу, отправив HTTP-запрос и прочитав ответ. Когда я отлаживаю, я до сих пор не могу понять, почему этот цикл while не передается.Хотя цикл прерывается, но код после него никогда не выполняется

void HttpSocket::Get(string address) 
{ 
    std::string response, host, httpRequest; 
    uint32_t ipAddress; 
    ParseRequest(address, host, httpRequest); 
    ResolveHostAddress(host, ipAddress); 
    HttpSocket::Connect(ipAddress); 
    strcpy(bufferToSend, httpRequest.c_str()); 
    n = write(sockfd,bufferToSend,strlen(bufferToSend)); 

    if (n < 0) { throw IO_Exception("Cannot send request.");  } 
    memset(bufferToSend, 0, 500); 

    memset(bufferToReceive, 0, 200); 
    n = read(sockfd,bufferToReceive,200); 

    if (n <= 0){ 
     throw IO_Exception("Cannot read response."); 
    } 
    else 
    { 
     response += bufferToReceive; 

     while(n != 0) 
     { 
      n = 0; 
      memset(bufferToReceive, 0, 200); 
      n = read(sockfd,bufferToReceive,200); 
      response += bufferToReceive; 
      cout << "still in the loop" << n << endl; 
     } 
     cout << "Response: " << response << endl; 
    } 
} 

Кстати n является volatile int таким образом, я не думаю, что оптимизация компилятор вызывает его. FYI, все нормально и работает до последнего цикла.

+1

Stack trace/error? – Jeff

+0

@Jeff без ошибок. Кстати, я работаю над Qt. Более того, «все еще в цикле» не печатается навсегда. Таким образом, я вижу, что программа выходит из системы while, но затем передает следующую строку кода – ozgur

+1

Подумайте об этом: у вас есть буфер 200 символов (я предполагаю, что вы не показываете фактическое объявление), и вы читаете (и потенциально заполните) весь этот буфер. Где же тогда ограничитель строки? Как вы считаете, когда вы обрабатываете этот буфер (без терминатора) как строку? –

ответ

3

::read() является синхронной функцией. Когда на вашем соке нет ничего, что нужно прочитать, звонок n = read(sockfd,bufferToReceive,200); только висит блоки ждут новую информацию.

Чтобы решить проблему, вы должны установить сокет non-blocking и читать его с ::recv(), который будет возвращать -E_WOULDBLOCK если нет доступных данных:

#include <fcntl.h> 
flags = ::fcntl(fd, F_GETFL, 0); 
flags |= O_NONBLOCK; 
::fcntl(fd, F_SETFL, flags); 

Альтернативные не будут проверять наличие данных до read в дескрипторе файла:

#include <sys/ioctl.h> 
int count; 
::ioctl(fd, FIONREAD, &count); 
+1

Поведение скорее называется _blocking_ not _ "hanging" _, но в любом случае ваш ответ правильный. –

+0

вы должны были отредактировать мой ответ, я определенно бы его принял;) – YSC

+0

Решенный. Спасибо. Проблема была проще, чем я думал, но очень фундаментальной, чтобы ее не видели. – ozgur

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