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



这是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,我不认为编译器优化会导致它。仅供参考,一切都很好,一直工作到最后一个循环。

::read()是一个

同步函数。当套接字上没有任何东西可以读取时,对n = read(sockfd,bufferToReceive,200);的调用只会挂起等待新信息的块。

要解决您的问题,您应该将套接字设置为非阻塞,并使用::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);

最新更新