views:

1352

answers:

3

I need to empty the data on a socket (making sure that there is nothing to receive). Unfortunately, there is no function for this in the python socket module.

I've implemented something this way:

def empty_socket(sock):
    """remove the data present on the socket"""
    input = [sock]
    while 1:
        inputready, o, e = select.select(input,[],[], 0.0)
        if len(inputready)==0: break
        for s in inputready: s.recv(1)

What do you think? Is there a better way to do that?


Update: I don't want to change the socket timeout. What's why i prefer a select to a read.


Update: The original question was using the 'flush' term. It seems that 'empty' is a better term.


Update - 2010-02-27 : I've noticed a bug when the pair has closed. The inputready is always filled with the sockets. I fixed that by adding a maximum number of loops. Is there a better fix?

A: 

Not sure if this will work, but you could attach a file object to the socket's file descriptor and call the flush() method on that file object:

import os

file_obj = os.fdopen(your_socket.fileno())
file_obj.flush()

This won't work in Windows because the descriptor returned by fileno() can't be passed to os.fdopen() in Windows

Steef
flush on file objects only flushes the output cached in userspace. Compare FILE* in C and fflush. Raw socket I/O is usually not buffered, and if it is then it's not buffered in userspace, and a fflush-like operation will not work. You may want to look at "push" for TCP.
Thomas
+1  A: 

Using select.select is good practice, as indicated in the Socket Programming HOWTO. You'll need to set the socket as non-blocking, using sock.setblocking(0).

Just a comment about nomenclature: flush is normally associated with output operations.

Vinay Sajip
+3  A: 

If by "flush" you mean throw away any pending incoming data then you can either use select() like you do, or set the socket to nonblocking and read in a loop until you're out of data.

Also note that (from the Linux manpage):

 Under Linux, select() may report a socket file descriptor as "ready for
 reading", while nevertheless a subsequent read blocks.  This could  for
 example  happen  when  data  has arrived but upon examination has wrong
 checksum and is discarded.  There may be other circumstances in which a
 file  descriptor is spuriously reported as ready.  Thus it may be safer
 to use O_NONBLOCK on sockets that should not block.

http://stackoverflow.com/questions/858282/spurious-readiness-notification-for-select-system-call

And as has been noted by others, "flush" usually refers to output.

Thomas
What would be the right term for "flushing" an input? Thanks for your answer
luc
Personally, I would call what you're doing "emptying" the socket. Although it does seem strange to me why you would want to do this - somebody sent you that data for a reason, why are you throwing it all away without processing it? :)
Glyph
cant we just do a recv with len to read as 0 after select returns?
Aditya Sehgal