Как правильно использовать select.poll () в Python3 для реализации эхо-TCP-сервера? - PullRequest
0 голосов
/ 05 июля 2019

Как правильно использовать select.poll () в Python3 для реализации эхо-TCP-сервера?

Я уже знаю, как использовать select.select() для опроса файловых дескрипторов.Этот метод прост в использовании, поскольку он принимает сокеты и возвращает сокеты в тройке списков.

Однако, с другой стороны, poll(), похоже, работает только с необработанными файловыми дескрипторами, поэтому мне нужно использоватьsocket.fromfd() каждый раз, когда я хочу использовать соответствующий объект сокета.Это делает poll() неудобным для программирования сокетов?

Кроме того, подключение к серверу ниже с использованием nc 127.0.0.1 8888 приводит к:

$ python poll_server.py 
New connection: 127.0.0.1:44504
Received: Hello

Traceback (most recent call last):
  File "poll_server.py", line 31, in <module>
    c = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
socket.error: [Errno 9] Bad file descriptor

Может кто-нибудь со знанием poll сказать мне, чтонеправильно, и если я правильно использую select.poll() для программирования сокетов?

import select
import socket
import os

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

s.bind(('127.0.0.1', 8888))
s.listen(5)

poll = select.poll()
poll.register(s, select.POLLIN | select.POLLPRI) # select.POLLERR

while(True):
    fds = poll.poll(1000)
    for fd, event in fds:
        if fd == s.fileno():
            # server socket
            c, addr = s.accept()
            poll.register(c, select.POLLIN | select.POLLPRI)
            print('New connection: {}:{}'.format(addr[0], addr[1]))
        else:
            # client socket
            c = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
            buf = c.recv(4096)
            if buf == None:
                print('Client disconnected')
                poll.unregister(fd)
                c.close()
            else:
                print('Received: {}'.format(buf.decode('utf-8')))
                c.send(buf)
s.close()
...