【发布时间】:2013-01-27 22:15:49
【问题描述】:
我正在尝试从套接字读取数据。出于某种我无法理解的原因,读取函数似乎进入了无限循环。我认为发生这种情况的原因是因为在使用 eclipse 进行调试时,调试器没有通过 read 函数。此外,当我使用终端运行程序时,它会永远运行。救命!!
附加信息:在 Linux 上运行,不确定是否与此问题有关,但我在程序中创建线程。
我想我应该提到的另一件事:第一次调用 read() 时,它按预期工作并读取套接字中的整个消息。当第二次再次调用 read() 时问题就开始了(当没有任何东西可以读取时)。我预计 read 会返回 0 来结束函数,但是 read 会进入无限循环。
这就是发生的一切:
read_write_res block_read_reply(int fd, void* buf, int max, int* read_size) {
int flag = 1;
if (read_size != NULL)
*read_size = 0;
int i;
while (1) {
i = read(fd, buf, max); /* HERE is where the debbuger gets stuck */
if (i == 0 && flag == 1) //nothing to read
continue;
if (i == 0 && flag == 0)
return READ_WRITE_SUCCESS;
if (i < 0){
return READ_WRITE_FAILURE;
if (i > 0 && read_size != NULL)
*read_size += i;
}
flag = 0;
max -= i;
buf = (char*) (buf) + i;
}
return READ_WRITE_SUCCESS;
}
【问题讨论】:
-
if (i == 0 && flag == 1) continue;...man read是你的朋友。 -
"成功则返回读取的字节数(零表示文件结束)"
-
请注意,对于 EAGAIN 和 EINTR 错误,您不应返回错误,而应重试。
-
@eyalm:
EAGAIN除非套接字是非阻塞的,否则不会发生,在这种情况下,立即重试不是你应该做的。EINTR通常根本不会发生(除非您安装了中断信号处理程序),如果发生了,是重试还是将其视为错误情况并不是那么明确。重试EINTR会破坏中断信号处理程序的目的,在这种情况下,您可能应该使用SA_RESTART安装它们...