Learning Python Network Programming

(Sean Pound) #1
Chapter 8
tincanchat.parse_recvd_data(data)
# If we have any messages, broadcast them to all
# clients
for msg in msgs:
msg = '{}: {}'.format(addr, msg)
print(msg)
broadcast_msg(msg)

# Send message to ready client
elif event & select.POLLOUT:
client = clients[fd]
data = client.send_queue.popleft()
sent = client.sock.send(data)
if sent < len(data):
client.sends.appendleft(data[sent:])
if not client.send_queue:
poll.modify(client.sock, select.POLLIN)

The crux of this program is the poll object, which we create at the start of execution.
This is an interface for the kernel's poll service, which lets us register sockets for the
OS to watch and notify us when they are ready for us work with them.


We register a socket by calling the poll.register() method, passing the socket as
an argument along with the type of activity that we want the kernel to watch out for.
There are several conditions which we can monitor by specifying various select.
POLL* constants. We're using POLLIN and POLLOUT in this program to watch out
for when a socket is ready to receive and send data respectively. Accepting a new
incoming connection on our listening socket will be counted as a read.


Once a socket is registered with poll, the OS will watch it and record when the
socket is ready to carry out the activity that we requested. When we call poll.
poll(), it returns a list of all the sockets that have become ready for us to work with.
For each socket, it also returns an event flag, which indicates the state of the socket.
We can use this event flag to tell whether we can read from (POLLIN event) or write
to the socket (POLLOUT event), or whether an error has occurred (POLLHUP, POLLERR,
POLLNVAL events).


To make use of this, we enter our event loop, repeatedly calling poll.poll(),
iterating through the ready objects it returns and operating on them as per their
event flags.

Free download pdf