# 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()
Это относительно просто. Идея состоит в том, чтобы написать код, который отслеживает любые типы событий, а затем научится обрабатывать каждый из них.
В этом случае запуск сервера, а затем клиента, создает следующий вывод сервера:
... и так продолжается вечно.
Итак, суммируйте мои выводы:
Закрытие клиента вызывает пару событий EPOLLIN и EPOLLHUP
Нет байтов данных для чтения из сокета
Не знаете, какие еще операции можно попробовать? (Я попробовал прочитать, поскольку это было единственное разумное решение, которое я мог придумать. Однако я не удивлен, что читать нечего.)
Эти события сохраняются, другими словами, цикл продолжается вечно, сообщая мне, что есть ожидающие события для EPOLLIN и EPOLLHUP для fd, связанного с клиентским сокетом.
И что мне здесь делать? Почему событие EPOLLIN генерируется а также событие EPOLLHUP?
Как мне обрабатывать каждое из них? Каждый тип события является сигналом. Обычно, если о чем-то подается сигнал, то следует что-то сделать для обработки этого сигнала. В этом случае бесконечный цикл продолжает сигнализировать о наличии ожидающих сигналов. Что нам с ними делать?
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() [/code] [code]# 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() [/code] Это относительно просто. Идея состоит в том, чтобы написать код, который отслеживает любые типы событий, а затем научится обрабатывать каждый из них. В этом случае запуск сервера, а затем клиента, создает следующий вывод сервера: [code]$ 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 [/code] ... и так продолжается вечно. Итак, суммируйте мои выводы: [list] [*]Закрытие клиента вызывает пару событий EPOLLIN и EPOLLHUP [*]Нет байтов данных для чтения из сокета Не знаете, какие еще операции можно попробовать? (Я попробовал прочитать, поскольку это было единственное разумное решение, которое я мог придумать. Однако я не удивлен, что читать нечего.) [*]Эти события сохраняются, другими словами, цикл продолжается вечно, сообщая мне, что есть ожидающие события для EPOLLIN и EPOLLHUP для fd, связанного с клиентским сокетом. [/list]И что мне здесь делать? Почему событие EPOLLIN генерируется а также событие EPOLLHUP? Как мне обрабатывать каждое из них? Каждый тип события является сигналом. Обычно, если о чем-то подается сигнал, то следует что-то сделать для обработки этого сигнала. В этом случае бесконечный цикл продолжает сигнализировать о наличии ожидающих сигналов. Что нам с ними делать?