Socket recv(1) seems to block instead of returning end of file.

Grant Edwards grante at visi.com
Thu Aug 23 13:57:22 EDT 2007


On 2007-08-23, Dan Stromberg - Datallegro <dstromberg at datallegro.com> wrote:
> On Thu, 23 Aug 2007 11:54:01 +0200, Hendrik van Rooyen wrote:
>
>> 
>> While doing a netstring implementation I noticed that if you
>> build a record up using socket's recv(1), then when you close
>> the remote end down, the recv(1) hangs, despite having a short
>> time out of  0.1 set.
>> 
>> If however, you try to receive more than one char, (I tested with 3,
>> did not try 2), then when you shut the remote end down you do not
>> get a time out, but an empty string - the normal end of file, I suppose.
>> 
>> Has anybody else seen this behaviour?
>> 
>> The transmit side seems to give a broken pipe error, which is fine.
>> 
>> I am using stock standard SuSe 10, Python 2.4, out of the box.
>> 
>> - Hendrik
>
> Are you using sock.settimeout()?

FWIW, I added a call to sock.setttimeout(0.2) to my example's
receive code and added 0.1 delays in the transmit code, and it
still seems to work fine:

-------------------------------8<-------------------------------------
#!/usr/bin/python

# writer
import socket,random,time

HOST = ''                 # Symbolic name meaning the local host
PORT = 8765               # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
print 'Connected to',((HOST,PORT))
total = 0
for i in range(10):
    data = "abcdefghijklmnopqrstuvwxyz"[:random.randint(1,20)]
    total += len(data)
    s.send(data)
    print "tx:",len(data)
    time.sleep(0.1)
s.close()
print total
-------------------------------8<-------------------------------------
#!/usr/bin/python

#reader
import socket

HOST = ''                 # Symbolic name meaning the local host
PORT = 8765               # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
conn.settimeout(0.2)
total = 0
while 1:
    data = conn.recv(1)
    total += len(data)
    print "rx:",len(data)
    if not data: break
conn.close()
print total
-------------------------------8<-------------------------------------

-- 
Grant Edwards                   grante             Yow! We have DIFFERENT
                                  at               amounts of HAIR --
                               visi.com            



More information about the Python-list mailing list