Как обработать событие EPOLLHUP?Python

Программы на Python
Ответить
Anonymous
 Как обработать событие EPOLLHUP?

Сообщение Anonymous »

Вот демонстрационный код:

Код: Выделить всё

# server.py

import socket
import select

import time

event_name_map = {
select.EPOLLIN: 'select.EPOLLIN',
select.EPOLLOUT: 'select.EPOLLOUT',
select.EPOLLPRI: 'select.EPOLLPRI',
select.EPOLLERR: 'select.EPOLLERR',
select.EPOLLHUP: 'select.EPOLLHUP',
select.EPOLLET: 'select.EPOLLET',
select.EPOLLONESHOT: 'select.EPOLLONESHOT',
select.EPOLLEXCLUSIVE: 'select.EPOLLEXCLUSIVE',
select.EPOLLRDHUP: 'select.EPOLLRDHUP',
select.EPOLLRDNORM: 'select.EPOLLRDNORM',
select.EPOLLRDBAND: 'select.EPOLLRDBAND',
select.EPOLLWRNORM: 'select.EPOLLWRNORM',
select.EPOLLWRBAND: 'select.EPOLLWRBAND',
select.EPOLLMSG: 'select.EPOLLMSG',
}

def main():

print(event_name_map)

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as server_socket:
print(f'server_socket.fileno: {server_socket.fileno()}')
server_socket.bind(('0.0.0.0', 12345))
server_socket.listen(10)

with select.epoll() as epoll:
SELECT_EVENT_TYPES = (
select.EPOLLIN |
select.EPOLLOUT |
select.EPOLLPRI |
select.EPOLLERR |
select.EPOLLHUP |
select.EPOLLET |
select.EPOLLONESHOT |
#select.EPOLLEXCLUSIVE |
select.EPOLLRDHUP |
select.EPOLLRDNORM |
select.EPOLLRDBAND |
select.EPOLLWRNORM |
select.EPOLLWRBAND |
select.EPOLLMSG
)
epoll.register(server_socket.fileno(), SELECT_EVENT_TYPES)

socket_fileno_map:dict[int, ssl.SSLSocket] = {}

while True:
events = epoll.poll(0.1)

for fileno, event in events:
print(f'event={event}: {fileno}')

if event & select.EPOLLIN:
print(f'EPOLLIN: {fileno}')

if fileno == server_socket.fileno():
connection, address = server_socket.accept()
print(f'connection from {address}')

connection_fileno = connection.fileno()
if connection_fileno in socket_fileno_map:
raise RuntimeError(f'fileno {connection_fileno} is already in the socket_fileno_map')
socket_fileno_map[connection_fileno] = connection
epoll.register(connection_fileno, select.EPOLLIN)

else:
for key, value in event_name_map.items():
if event & key:
print(f'pending event {value} from file handle {fileno}')

tmp_socket = socket_fileno_map[fileno]
if event & select.EPOLLIN:
data = tmp_socket.read(10000)
print(data)
print(len(data))
elif event & select.EPOLLHUP:
print('EPOLLHUP event')

time.sleep(1.0)

if event & select.EPOLLOUT:
print(f'EPOLLOUT: {fileno}')

if event & select.EPOLLHUP:
print(f'EPOLLHUP: {fileno}')

epoll.unregister(server_socket.fileno())

if __name__ == '__main__':
main()

Код: Выделить всё

# client.py

import socket
import ssl

import time

def main():

hostname = 'localhost'

with socket.create_connection((hostname, 12345)) as client_socket:
print(f'closing')
client_socket.close()
time.sleep(5.0)
print(f'closed')

if __name__ == '__main__':
main()
Это относительно просто. Идея состоит в том, чтобы написать код, который отслеживает любые типы событий, а затем научится обрабатывать каждый из них.
В этом случае запуск сервера, а затем клиента, создает следующий вывод сервера:

Код: Выделить всё

$ python3 server.py
{1: 'select.EPOLLIN', 4: 'select.EPOLLOUT', 2: 'select.EPOLLPRI', 8: 'select.EPOLLERR', 16: 'select.EPOLLHUP', 2147483648: 'select.EPOLLET', 1073741824: 'select.EPOLLONESHOT', 268435456: 'select.EPOLLEXCLUSIVE', 8192: 'select.EPOLLRDHUP', 64: 'select.EPOLLRDNORM', 128: 'select.EPOLLRDBAND', 256: 'select.EPOLLWRNORM', 512: 'select.EPOLLWRBAND', 1024: 'select.EPOLLMSG'}
server_socket.fileno: 3
server_socket.fileno: -1
ssl_socket.fileno: 3
event=65: 3
EPOLLIN: 3
connection from ('127.0.0.1', 50624)
event=17: 5
EPOLLIN: 5
pending event select.EPOLLIN from file handle 5
b''
0
pending event select.EPOLLHUP from file handle 5
b''
0
EPOLLHUP: 5
event=17: 5
EPOLLIN: 5
pending event select.EPOLLIN from file handle 5
b''
0
pending event select.EPOLLHUP from file handle 5
b''
0
EPOLLHUP: 5
event=17: 5
EPOLLIN: 5
... и так продолжается вечно.
Итак, суммируйте мои выводы:
  • Закрытие клиента вызывает пару событий EPOLLIN и EPOLLHUP
  • Нет байтов данных для чтения из сокета
    Не знаете, какие еще операции можно попробовать? (Я попробовал прочитать, поскольку это было единственное разумное решение, которое я мог придумать. Однако я не удивлен, что читать нечего.)
  • Эти события сохраняются, другими словами, цикл продолжается вечно, сообщая мне, что есть ожидающие события для EPOLLIN и EPOLLHUP для fd, связанного с клиентским сокетом.
И что мне здесь делать? Почему событие EPOLLIN генерируется а также событие EPOLLHUP?
Как мне обрабатывать каждое из них? Каждый тип события является сигналом. Обычно, если о чем-то подается сигнал, то следует что-то сделать для обработки этого сигнала. В этом случае бесконечный цикл продолжает сигнализировать о наличии ожидающих сигналов. Что нам с ними делать?

Подробнее здесь: https://stackoverflow.com/questions/792 ... lhup-event
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»