我正在编写一个C客户机-服务器程序,其中客户机必须从服务器接收大量数据。由于我希望我的客户端在服务器出问题时(例如,在发送数据时停止运行),不要无限期地在.replace(/\"/g, "")
上等待,因此我选择使用{ linux man page。
我的代码如下:
{JSON.stringify(lconfigInfo.sql[configInfoKey]).replace(/\"/g, "")}
其中recv()
是与套接字关联的文件描述符,poll()
设置为5秒,由于我想读取数据,因此我将while (...)
{
struct pollfd fds;
fds.fd = sock;
fds.events = POLLIN;
retry:
r = poll(&fds, 1, TIMEOUT*1000);
if (r == -1 && errno == EINTR)
goto retry;
else if (r == -1)
err_sys("poll() failed");
else if (r == 0)
err_sys("timeout expired");
recv(...)
}
指定为事件。
问题
据人:
timeout参数指定poll()的毫秒数 应该阻止等待文件描述符准备就绪。通话 会一直阻塞,直到:
sock
但是,即使我在停止服务器后立即超时(我使用valgrind),程序仍在TIMEOUT
函数上无限期地阻塞。我还尝试将事件设置为POLLIN
(以适应某些特殊情况),但是没有用。我多次阅读了文档,但不知道是什么原因导致了这个问题。
其他信息
我正在使用Xubuntu 18.04,gcc版本7.4.0,目标x86_64
答案 0 :(得分:1)
即使没有可读取的数据,您的代码也会无条件地调用recv()
。实际上,如果fds.revents
没有返回错误/超时,您将完全忽略poll()
字段。
您的循环应如下所示:
struct pollfd fds;
fds.fd = sock;
fds.events = POLLIN;
do {
r = poll(&fds, 1, TIMEOUT*1000);
if (r == -1) {
if (errno == EINTR) continue;
perror("poll() failed");
break;
}
else if (r == 0) {
printf("timeout expired");
break;
}
else if (fds.revents & POLLIN) {
r = recv(...);
if (r < 0) {
perror("recv() failed");
break;
}
else if (r == 0) {
printf("socket disconnected\n");
break;
}
else {
// process data as needed...
}
}
else if (fds.revents & (POLLERR | POLLNVAL)) {
printf("socket error\n");
break;
}
}
while (1);
close(sock);