0

我使用 epoll 构建服务器,这是我初始化 epoll 的代码:

core->fd_epoll = epoll_create(LIMIT_CLIENT);
ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
ev.data.fd = core->socket_main;
epoll_ctl(core->fd_epoll, EPOLL_CTL_ADD, core->socket_main, &ev);
while (1)
{
  nfds = epoll_wait(core->fd_epoll, &ev, 90000, -1);
  ...
}

当我用它来检查我的 fds 上是否有新东西时:

for (i = 0; i < nfds; i++)
{
  fd = ev[i].data.fd;
  if (fd == core->socket_main)
    {
      socket_fils = socket_accept(core->socket_main, 0);
      event.data.fd = socket_fils;
      event.events = EPOLLIN | EPOLLET | EPOLLRDHUP;
      xepoll_ctl(core->fd_epoll, EPOLL_CTL_ADD, socket_fils, &event);
      printf("Incoming => FD fils %d\n", socket_fils);
    }
  else
    printf("Event %x\n", ev[i].events);
}

当我使用 netcat 向服务器发送消息时,位域事件等于 1 (EPOLLIN) 当我发送 ctrl+c 时,netcat 退出并且我的位域等于 2001 (EPOLLIN 和 EPOLLRDHUP) 当我发送 ctrl+d ,netcat 没有退出,但我的位域也等于 2001 ......

在 ctrl+d 之后,我的服务器关闭了套接字。这不正常... ctrl+d 不应该关闭套接字并返回不同的位域。

在服务器中,我怎么知道它是 ctrl+c 还是 ctrl+d ?

谢谢你。

4

1 回答 1

3

ctrl您的服务器无法直接“看到”正在运行 netcat 的终端上的+cctrl+按键。d它们分别导致将 SIGINT 信号发送到 netcat,并导致 netcat 在其标准输入上看到 EOF 条件。netcat 对此的作用实际上取决于 netcat,而不是取决于您的服务器。以下是他们为我做的事情:

  • ctrl+c将 SIGINT 发送到 netcat: netcat 被杀死,因为这是 SIGINT 的默认操作,而 netcat 不会更改它。当 netcat 死掉时,套接字会自动关闭。服务器将此感知为可用的传入数据,与EPOLLIN|EPOLLRDHUP您看到的情况一致。如果你阅读socket,你会发现一个EOF在等着你。

  • ctrl+d在 netcat 的标准输入上发送 EOF:netcat 注意到了 EOF。它不会通过套接字发送更多数据。但是,如果服务器有更多数据要发送,它会继续运行并从套接字读取。

换句话说,我无法重现您看到的 netcat 行为(使用 Linux 2.6 和 netcat v1.10-38)。也许您的 netcat 版本在读取标准输入上的 EOF 后会关闭套接字以进行写入?

于 2012-06-11T16:39:56.720 回答