如何在Python3中正确使用select.poll()实现回显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()