Используйте kqueue для определения зависания на другой стороне сокета или исключительного состояния сокета - PullRequest
3 голосов
/ 03 августа 2010

Я прочитал man 2 kqueue, но не узнал, как я могу получать уведомления о зависании сокета или исключительном состоянии сокета, не регистрируя его с помощью EVFILT_READ или EVFILT_WRITE.Кроме этого, не совсем понятно, как kqueue сигнализирует об исключительных состояниях сокетов.

Спасибо за ваш ответ заранее.

1 Ответ

1 голос
/ 03 августа 2010

Хитрость, которую можно использовать для получения событий EOL при игнорировании всех событий READ, заключается в предоставлении смехотворно высокого значения для NOTE_LOWAT, таким образом подавляя все события READ.

Вот пример, выполняющий это в Python REPL:

Python 2.6.5 (r265:79063, Jul 17 2010, 22:57:01) 
[GCC 4.2.1 20070719  [FreeBSD]] on freebsd8
Type "help", "copyright", "credits" or "license" for more information.
>>> import select
>>> import socket
>>> import sys
>>> a, b = socket.socketpair()
>>> kq = select.kqueue()
>>> kq.control([select.kevent(a, select.KQ_FILTER_READ, select.KQ_EV_ADD, select.KQ_NOTE_LOWAT, sys.maxint)], 0)
[]
>>> b.send('abc')
3
>>> kq.control(None, 10) # Interrupt after some time.
^CTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyboardInterrupt
>>> b.close()
>>> kq.control(None, 10) # Immediate return.
[<select.kevent ident=3 filter=-1 flags=0x8000 fflags=0x0 data=0x3 udata=0x0>]
>>> 

Более того, во FreeBSD не существует такого понятия, как исключительное состояние, которое можно процитировать man 2 select:

Единственное обнаруживаемое исключительное состояние - это принятые данные вне диапазона.на розетке.

...