Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C poll()无限期等待,但指定了超时_C_Server_Client_Polling_Unix Socket - Fatal编程技术网

C poll()无限期等待,但指定了超时

C poll()无限期等待,但指定了超时,c,server,client,polling,unix-socket,C,Server,Client,Polling,Unix Socket,我正在编写一个C客户机-服务器程序,其中客户机必须从服务器接收大量数据。由于我希望我的客户机不要在服务器出现问题时无限期地等待recv()(例如,在发送数据时停止),因此我选择使用中指定的poll()函数 我的代码如下所示: while (...) { struct pollfd fds; fds.fd = sock; fds.events = POLLIN; retry: r = poll(&fds, 1, TIMEOUT*1000); if (r == -1 &

我正在编写一个C客户机-服务器程序,其中客户机必须从服务器接收大量数据。由于我希望我的客户机不要在服务器出现问题时无限期地等待
recv()
(例如,在发送数据时停止),因此我选择使用中指定的
poll()
函数

我的代码如下所示:

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(...)
}
其中,
sock
是与套接字关联的文件描述符,
TIMEOUT
设置为5秒,我指定
POLLIN
作为事件,因为我对读取数据感兴趣

问题

据曼恩说:

timeout参数指定轮询()的毫秒数 应阻止等待文件描述符就绪。电话 将阻止,直到:

   (1)  a file descriptor becomes ready;

   (2)  the call is interrupted by a signal handler; or

   (3)  the timeout expires.
但是,程序会无限期地阻塞
poll()
函数,即使我一停止服务器超时(我使用了valgrind)。我还尝试将事件设置为
POLLIN | POLLPRI
(以捕获一些异常情况),但没有成功。我多次阅读文档,无法找出导致此问题的原因

其他信息


我使用的是Xubuntu 18.04,gcc版本7.4.0,目标x86_64

您的代码无条件地调用
recv()
,即使没有数据可读取。事实上,如果
poll()
没有返回错误/超时,则完全忽略了
fds.revents
字段

您的循环应该更像这样:

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);
struct pollfd fds;
fds.fd=袜子;
fds.events=POLLIN;
做{
r=轮询(&fds,1,超时*1000);
如果(r==-1){
如果(errno==EINTR)继续;
perror(“poll()失败”);
打破
}
else如果(r==0){
printf(“超时过期”);
打破
}
否则如果(fds.revents&POLLIN){
r=recv(…);
if(r<0){
perror(“recv()失败”);
打破
}
else如果(r==0){
printf(“套接字断开连接\n”);
打破
}
否则{
//根据需要处理数据。。。
}
}
否则如果(fds.revents和(POLLERR | POLLNVAL)){
printf(“套接字错误\n”);
打破
}
}
而(1),;
关闭(袜子);

通过
strace
运行程序?为什么使用
goto
而不是正常的
do/while
循环?请阅读,因为您只发布了一段代码,很难理解示例代码(没有
sock
的声明只给出了
,而
循环没有精确的测试表达式,并且没有对
poll
系统调用进行完整的错误检查。)非常感谢,伙计!我假设在
fds.events
中设置
POLLIN
标志,
recv
的返回值不能为0,因为总是有数据要读取。