【问题标题】:select() on STDIN and Incoming SocketSTDIN 和传入套接字上的 select()
【发布时间】:2017-01-17 02:12:06
【问题描述】:

我正在尝试用 C 语言编写一个非常基本的聊天客户端,它使用套接字与另一台机器进行通信,但我在理解 select 方面遇到了一些问题。这是相关代码的快速sn-p。

while(1)
  {
    FD_ZERO(&readfds);
    FD_ZERO(&writefds);

    FD_SET(STDIN, &writefds);
    FD_SET(connectFD, &readfds);

    select(connectFD+1, &readfds, &writefds, NULL, NULL);

    if(FD_ISSET(connectFD, &readfds) != 0)
    {
      char buf[1024];
      memset(buf, 0, sizeof(buf));
      int lastBit;

      lastBit = recv(connectFD, buf, sizeof(buf), 0);
      if (lastBit > 0 && lastBit < 1024)
      {
        buf[lastBit] = '\0';
      }
      else
      {
        close(connectFD);
        break;
      }
      printf("%s\n", buf);
    }

    else if (FD_ISSET(STDIN, &writefds))
    {
      char msg[1024];
      memset(msg, 0, sizeof(msg));
      read(STDIN, msg, sizeof(msg));
    }
  }
}

我想要做的是在传入消息到达后立即处理它们,并且只有在我按 ENTER 后才发送传出消息,但我现在只在我按 ENTER 后处理传入数据,而不是立即处理。我认为这是因为 read 是一个阻塞调用,并且当缓冲区中有任何数据时 select 正在返回,而不仅仅是当有换行符时(即 read 返回时),但我不知道如何处理这个。有什么建议或技巧可以引导我走上正确的道路吗?

非常感谢你们!

【问题讨论】:

  • 如果您确实读取了 1,024 字节,为什么要尝试读取 1,024 字节?
  • 这只是一个非常基本(而且错误)的缓冲区溢出检查。一旦我得到程序的实际逻辑工作,我将在稍后修复它。 @大卫施瓦茨

标签: c sockets select network-programming


【解决方案1】:
FD_SET(STDIN, &writefds);

您想从 STDIN 读取,因此您应该将 STDIN 添加到 &amp;readfds 而不是 &amp;writefds。写入 STDIN 几乎总是可能的,因此您的代码有效地获得了可以写入 STDIN 的信息,但随后尝试从 STDIN 读取并挂在那里直到读取实际成为可能。

【讨论】:

  • 哦,伙计,我知道我错过了一些基本的东西。我认为由于来自 STDIN 的输入,我会写入(到套接字),因此它需要在 writefds 集中。现在一切正常。非常感谢!
猜你喜欢
  • 2020-08-26
  • 1970-01-01
  • 2010-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-28
相关资源
最近更新 更多