如何通知异常客户端终止服务器?

时间:2013-08-09 10:55:46

标签: c signals freebsd kqueue berkeley-sockets

由于Title已经说过我正在寻找一种方法,当客户关闭会话时会收到通知。

我正在使用freeBSD操作系统。 服务器使用Xamount线程运行(取决于CPUcore数量)。所以我没有分叉,每个客户都没有自己的流程。

这就是为什么发送一个死亡包,所有time_t秒,来回复一个SIGPIPE不是我的选择。 但是我需要从kqueue中删除左边的客户端,因为否则在接受太多的accept()后,我的代码显然会遇到内存问题。

有没有办法,我可以检查每个客户端没有高性能松散,它们是否已连接?

或任何事件通知,如果发生这种情况会触发?或者,在客户端进程退出之前,是否有办法让程序将任何信号发送到端口,即使是在异常终止的情况下?

2 个答案:

答案 0 :(得分:1)

编辑:答案错过了这个问题,因为它不是关于使用kqueue的。但如果其他人通过标题找到问题,那么无论如何它都可能有用......

我经常看到以下行为:如果客户端死机,并且服务器在客户端的套接字描述符上执行select()select()将返回返回码>对于该描述符,0和FD_ISSET( fd )将为真。但是,当您现在尝试从套接字读取时,read()(或recv())将返回ERROR。

使用它来检测客户端死亡的“正常”连接对我们来说很好,但是当套接字连接通过隧道时似乎有不同的行为,但我们还没有设法完全解决这个问题。

答案 1 :(得分:0)

根据kqueue man pagekevent()应该在套接字关闭时创建一个事件。来自过滤器EVFILT_READ的说明:

  

EVFILT_READ

     

将描述符作为标识符,并在有可读数据时返回。根据描述符类型,过滤器的行为略有不同。

     

套接字

     

先前传递给listen()的套接字在有传入连接挂起时返回。 data包含listen backlog的大小。

     

当有数据要读取时,其他套接字描述符将返回,这取决于套接字缓冲区的SO_RCVLOWAT值。通过在fflags中设置NOTE_LOWAT标志并在数据中指定新的低水位标记,可以在添加过滤器时使用每过滤器低水位标记覆盖此值。返回时,数据包含可读取的协议数据的字节数。

     

如果套接字的读取方向已关闭,则过滤器还会在标志中设置EV_EOF,并在fflags中返回套接字错误(如果有)。可以返回EOF(表示连接已经消失,而套接字中仍有待处理的数据               缓冲液中。