Detection of subsequent data by poll()

Donn Cave donn at u.washington.edu
Fri Dec 7 00:41:46 CET 2001


Quoth rupe at metro.yak.net (Rupert Scammell):
| > Quoth rupe at metro.yak.net (Rupert Scammell):
| > | I recently wrote a program that uses the select.poll() method in order
| > | to
| > | check for incoming data on multiple listening sockets.  When I open a
| > | connection to one of the listening sockets (e.g. via telnet), the
| > | program accepts the first item of data sent (a character string with a
| > | trailing CRLF).  However, subsequent calls to poll() never appear to
| > | detect more strings sent in the same connection to this socket.  The
| > | file descriptors for the sockets are all correctly registered with the
| > | poll object.
| > |
| > | Is there a way to make poll() detect this incoming data without having
| > | to close and re-open a connection to the socket in question each time?
| > |
| > | Any suggestions would be appreciated!

| Per Donn Cave's request, the source of the program that's producing
| the problem is provided below.  The system in use is a RH Linux 6.2
| machine (x86 architecture), running kernel version 2.4.13.  Again, any
| assistance or insight into why the poll() call made against the poll
| object is failing to return more than the first sent line of data
| would be greatly appreciated.

In this program, poll() doesn't really detect the first line, either.
You register only the service sockets, so you detect connections.
Then on connect, you accept(), and you infer the existence of the
first line.

If you want poll() to see the first line, you have to register
the cur_conn_obj you get from accept().  This should make sense:
in general, if you want poll to tell you there's data to be read
on X, you must give it X to look at.

	Donn Cave, donn at u.washington.edu
----------------------------------------
| Polling code source:
|
| import sys, socket, select
|
| # Create polling object.
| poll_obj = select.poll()
|
| # List of ports to open
| port_list = [8555, 8556, 8557, 8558]
|
| # List of associated file descriptor numbers.  These match up
| # by subscript with the values in port_list, above.
| fileno_list = []
|
| # List of socket objects.
| sock_obj_list = []
|
| # Number of sockets to create:
| num_sockets = len(port_list)
|
| # Create socket objects for each port in port_list, append to
| sock_obj_list,
| # then bind and listen on each.
| for i in range(num_sockets):
|     print 'entering socket addition FOR, port: ', port_list[i]
|     sock_obj_list.append(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
|     sock_obj_list[i].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|     sock_obj_list[i].bind(('',port_list[i]))
|     sock_obj_list[i].listen(1)
|     
|
|     # Add the file descriptor to fileno_list:
|     fileno_list.append(sock_obj_list[i].fileno())
|
|     # Register the fd with poll_obj.
|     poll_obj.register(sock_obj_list[i])
|
| # Poll for data on each of the registered socket objects.
|
| print 'fileno_list: ', fileno_list
| print 'sock_obj_list: ', sock_obj_list
|
|
| while 1:
|     # Start with an empty list that'll contain data from
|     # our sockets that have events.
|     data_list = []
|
|     # Poll for data on each of the sockets.
|     print 'Polling...'
|     event_list = poll_obj.poll()
|     print 'event_list', event_list
|
|     # Number of socket objects returned.
|     event_count = len(event_list)
|     print 'event count: ', event_count
|
|     """
|     Match the file descriptor values returned by .poll() into event_list with
|     the socket that has that file descriptor value in sock_obj_list.
|     Once we know the socket, call .accept() on it, then read 1024 bytes of data
|     from it.  Then print the list of retrieved data.  Each item in the list is a
|     two item tuple in the form (port_number, retrieved_data).
|     """
|
|     for i in range(event_count):
|         current_fd = event_list[i][0]
|         for b in range(num_sockets):
|             if (current_fd == fileno_list[b]):
|                 (cur_conn_obj, cur_addr) = sock_obj_list[b].accept()
|                 data_list.append([port_list[b], cur_conn_obj.recv(1024)])
|     print data_list



More information about the Python-list mailing list