虽然循环中断,但它之后的代码永远不会执行

时间:2015-11-16 18:06:33

标签: c++ sockets while-loop

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

顺便说一下,nvolatile int,我不认为编译器优化会导致它。仅供参考,一切都很好,一直工作到最后一次循环。

1 个答案:

答案 0 :(得分: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);