Python socket.accept неблокирует? - PullRequest
17 голосов
/ 15 марта 2011

Есть ли способ, которым я могу использовать python socket.accept () неблокирующим способом, который просто запускает его и позволяет мне просто проверить, есть ли новые подключения?Я действительно не хочу использовать многопоточность.Спасибо.

Ответы [ 2 ]

31 голосов
/ 15 марта 2011

Возможно, вы хотите что-то вроде select.select() (см. документация ).Вы предоставляете select() три списка сокетов: сокеты, которые вы хотите отслеживать на предмет читабельности, возможности записи и состояния ошибок.Сокет сервера будет доступен для чтения при ожидании нового клиента.

Функция select() будет блокироваться до тех пор, пока не изменится одно из состояний сокета.Вы можете указать необязательный четвертый параметр, timeout, если не хотите блокировать навсегда.

Вот пример тупого эхо-сервера:

import select
import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('', 8888))
server_socket.listen(5)
print "Listening on port 8888"

read_list = [server_socket]
while True:
    readable, writable, errored = select.select(read_list, [], [])
    for s in readable:
        if s is server_socket:
            client_socket, address = server_socket.accept()
            read_list.append(client_socket)
            print "Connection from", address
        else:
            data = s.recv(1024)
            if data:
                s.send(data)
            else:
                s.close()
                read_list.remove(s)

Python также имеет epoll, poll и kqueue реализации для платформ, которые их поддерживают.Это более эффективные версии select.

2 голосов
/ 15 марта 2011

Вы можете вызвать метод setblocking(0) в Socket, чтобы сделать его неблокирующим.Посмотрите на асинхронный модуль или структуру, подобную Twisted .

...