How does the select () function in the Python select module work exactly?

I am working on writing a network application in Python. I previously worked on the use of blocking sockets, but after a better understanding of the requirements and concepts, I want to write an application using non-blocking sockets and, therefore, an event driven server.

I understand that functions in the select module in Python should be used to conveniently see which socket interests us, etc. To the fact that I basically tried to flip a few examples of an event-driven server, and I came across this:

""" An echo server that uses select to handle multiple clients at a time. Entering any line of input at the terminal will exit the server. """ import select import socket import sys host = '' port = 50000 backlog = 5 size = 1024 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((host,port)) server.listen(backlog) input = [server,sys.stdin] running = 1 while running: inputready,outputready,exceptready = select.select(input,[],[]) for s in inputready: if s == server: # handle the server socket client, address = server.accept() input.append(client) elif s == sys.stdin: # handle standard input junk = sys.stdin.readline() running = 0 else: # handle all other sockets data = s.recv(size) if data: s.send(data) else: s.close() input.remove(s) server.close() 

Parts that I did not seem to understand are as follows:

In the code snippet inputready,outputready,exceptready = select.select(input,[],[]) I believe that the select() function returns three possible empty lists of expected objects for input, output and exceptional conditions. Therefore, it makes sense that the first argument to the select() function is a list containing the server socket and stdin. However, when I run into confusion, in the else block of the code.

Since we are looping over the inputready socket list, it is clear that the select() function will select a client socket that is ready to read. However, after we read the data using recv() and find that the socket actually sent the data, we would like to send it back to the client. My question is, how can we write to this socket without adding it to the list passed as the second argument to the select() function call? Sense, how can we call send() directly on a new socket without registering it with select() as a writable socket?

In addition, why do we focus only on read-only sockets (in this case already entered)? Isn't it even necessary to iterate over the outputready list to see which sockets are ready for writing? Obviously I'm missing something here.

It would also be useful if someone could explain the operation of select() in more detail or point to good documentation.

Thanks.

+7
python select sockets network-programming
source share
1 answer

This code snippet is probably just a simple example, and therefore it is not exhaustive. You can write and read on each socket, also if the chosen one does not tell you that they are ready. But, of course, if you do this, you cannot be sure that your send () will not be blocked. Thus, yes, it would be best practice to rely on the selection also for write operations. There are also many other functions that have a similar purpose, and in many cases they are better chosen (e.g. epoll ), but they are not available on all platforms. Information on selection, epoll, and other features can be found on the Linux manual pages.

However, in python there are many good libraries used to handle many connections, some of them: Twisted and gevent

+1
source share

All Articles