Question

I would like to send a message to a subset of clients connected to a server which uses Python epoll. Is there a practical way of getting list of fileno's of connected clients?

Was it helpful?

Solution

Normally, the way you handle this is to keep track of the clients yourself. Every time you accept a new client, before adding it to the epoll, also add it to your collection. Every time you drop a client, remove it from your collection.

The typical minimal thing to store is a dict mapping sockets to whatever else you need to keep track of. You can use the socket itself, a weakref to it, or its fileno as the key. The data you need often includes things like a read buffer and a write buffer, the peer address (as received on accept), a name or user ID or auth cookie, etc.

And I'm not sure how you're doing anything useful with a polling server that doesn't have at least a read buffer attached to each client socket. What do you do when you get a partial message? (For that matter, if you're planning to send a message to these clients, and you don't have a write buffer, how are you going to do that?)


But to answer your specific question:

There is no way to get a list of fd's from a Python epoll object, because there is no way to do this with the underlying API.

Conceivably, you could write something that steps through everything from 0 to your max open fd and tries to do an epoll_ctl with it and distinguish based on the error. This is probably a very bad idea, but it may not be impossible. You'd probably have to ctypes down to the native function, and you may need to play around with different possibilities to find out what has the right effect. For example, maybe if you do epoll_ctl(my_epoll.fileno(), EPOLL_CTL_MOD, fd, NULL), you'll get ENOENT for a unregistered fd, EBADF for a nonexistent fd, but EINVAL (because of the NULL event) for a valid fd. Or maybe it'll segfault. I can't guarantee there's any combination of parameters that will distinguish, but with some trial and error, you might find one.

(By the way, there's nothing that says that an epoll has to be a list of connected clients; e.g., it may be the connected clients plus the listener socket plus a "quit" pipe.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top