Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python socket.accept nonblocking?

Tags:

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.

like image 414
pajm Avatar asked Mar 15 '11 06:03

pajm


People also ask

Is socket accept blocking?

All IBM® TCP/IP Services socket APIs support nonblocking socket calls. Some APIs, in addition to nonblocking calls, support asynchronous socket calls. The default mode of socket calls is blocking. A blocking call does not return to your program until the event you requested has been completed.

How do you mark a socket as nonblocking?

To mark a socket as non-blocking, we use the fcntl system call. Here's an example: int flags = guard(fcntl(socket_fd, F_GETFL), "could not get file flags"); guard(fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK), "could not set file flags"); Here's a complete example.

How do you use a non-blocking socket in python?

In Python, you use socket. setblocking(False) to make it non-blocking.

What is blocking and nonblocking in Python?

If a function is doing some task which is making the CPU work, then it is blocking the function from returning. Similarly, if a function is trying to get something from the database, then it is going to wait for the result to come and will block until then to continue the processing.


1 Answers

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.

like image 126
Nathan Ostgard Avatar answered Sep 19 '22 14:09

Nathan Ostgard