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