Python socket.accept nonblocking?
Asked Answered
Y

3

29

Is there a way I can use python's socket.accept() in a non-blocking way that simply runs it and lets me just check if it got any new connections? I really don't want to use threading. Thanks.

Yasukoyataghan answered 15/3, 2011 at 6:6 Comment(0)
P
42

You probably want something like select.select() (see documentation). You supply select() with three lists of sockets: sockets you want to monitor for readability, writability, and error states. The server socket will be readable when a new client is waiting.

The select() function will block until one of the socket states has changed. You can specify an optional fourth parameter, timeout, if you don't want to block forever.

Here is a dumb echo server example:

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 also has epoll, poll, and kqueue implementations for platforms that support them. They are more efficient versions of select.

Photocell answered 15/3, 2011 at 6:18 Comment(0)
D
4

You can invoke the setblocking(0) method on the Socket to make it non-blocking. Look into the asyncore module or a framework like Twisted.

Decigram answered 15/3, 2011 at 6:16 Comment(2)
I tried that, and got the error that "A non-blocking socket operation could not be completed immediately"Yasukoyataghan
@Yasukoyataghan what else do you expect to happen if a non-blocking operation has nothing to do? By the way I wouldn't call that an error.Saddleback
I
0

You can make select non-blocking by setting the timeout parameter to 0. In that case select polls. See https://docs.python.org/3/library/select.html

Immesh answered 9/2, 2023 at 9:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.