【问题标题】:FD_ISSET keeps reading though there's no data in c尽管 c 中没有数据,但 FD_ISSET 一直在读取
【发布时间】:2013-10-20 13:35:49
【问题描述】:

我在监听多个套接字时遇到问题。我有一个监听一堆套接字的函数,但是当我测试并且只在其中一个套接字上发送数据时; FD_ISSET 方法为每个套接字持续返回 true,并且对于我也没有发送数据的套接字,缓冲区中没有返回数据(因为没有数据)。我正在使用每个套接字进行发送和接收。 我做错了什么?

编辑:发生的事情是 printf 语句打印了多次,而它应该只打印一次,因为我只在 1 个套接字上发送了数据。我已经添加了对 read()>0 的返回值的测试,它仍然没有乐趣。

void receive(struct nodeData *nd, struct sockInfo *si){
    char buffer[MAXBUF];
    struct timeval timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = 1000;

    // ----Wait in select until file descriptors change----
    int y = select(si->maxFD, &si->fd_read_set, NULL, NULL, &timeout);
    printf("ID: %d  Y %d\n", nd->id, y);
    if (y <= 0)
        return;
    for (int i=0; i < nd->netTopo->n; i++) {
        /* ----Was it child i---- */
        if (FD_ISSET(si->mastFD[i], &si->fd_read_set)) {
            read(si->mastFD[i], buffer, MAXBUF);
            printf("%d %d %d \n",buffer[0], buffer[1], buffer[2]); //  For Testing
        }
    }
}

【问题讨论】:

  • 每次拨打select()时,您是否都在重置fd_read_set?你需要,因为select() 改变了它,但你没有显示正在准备fd_readset`的代码。
  • 不,我不会每次都重置读取集。我将它归零一次然后设置它。每次我会在哪里重置 FD_SET ?
  • 我在重置,但仍然没有乐趣
  • 请更新您的问题以显示您的最新代码。每次调用select() 时,您必须将fd_set 置零+设置。

标签: c sockets


【解决方案1】:

您忽略了read 的返回值。 EOF 是一个可读条件(导致select 将文件描述符报告为可读,即FD_ISSET 返回true),您需要通过read 返回0 来检测它。在EOF 之后,您可能想要关闭文件描述符并删除它从设置到select上。

【讨论】:

  • 感谢您的回复。这些监听套接字是持久套接字,我需要在不久之后发送它们。所以仍然关闭它们并将它们从集合中移除?
  • 是的。当select() 报告一个套接字是可读的,然后read() 从该套接字返回 0 时,这意味着对等端已关闭其端的连接,因此您需要关闭该端的该套接字并停止使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多