Unix:Epoll,在服务器中捕获ctrl + d和ctrl + c

时间:2012-06-11 14:10:52

标签: sockets unix networking epoll

我使用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?

谢谢。

1 个答案:

答案 0 :(得分:3)

运行netcat的终端上的 ctrl + c和ctrl + d按键不能由服务器直接“看到”。它们分别导致SIGINT信号被发送到netcat,以及netcat在其stdin上看到的EOF条件。 netcat对此做了什么真的取决于netcat,而不是你的服务器。这是他们为我做的事情:

  • ctrl + c将SIGINT发送到netcat :netcat被终止,因为这是SIGINT的默认操作,netcat不会更改它。当netcat死亡时,套接字会自动关闭。服务器将此视为可用的传入数据,与您看到的EPOLLIN|EPOLLRDHUP条件一致。如果您阅读了套接字,您会发现EOF正等着您。

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

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