Here is a short python program that illustrates what I mean. If you
remove the send('die') line, it works flawlessly, but with it in, the
reset is 100% repeatable.
My question is, why does the send by the server change the semantics of
the close on the client?
Thanks,
-Jonathan
---- code follows ----
#!/usr/bin/python
import socket, threading, time
def recv():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 8000))
sock.listen(1)
s, _ = sock.accept()
s.send('die')
time.sleep(1)
data = ''
while True:
t = s.recv(10000)
if not t:
break
data += t
print len(data)
threading.Thread(target=recv).start()
def send():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('127.0.0.1', 8000))
s = 'asdf'*100000;
sock.sendall(s)
sock.close()
time.sleep(0.1) # let recv thread set up
send()
> Here is a short python program that illustrates what I mean. If you
> remove the send('die') line, it works flawlessly, but with it in, the
> reset is 100% repeatable.
> My question is, why does the send by the server change the semantics of
> the close on the client?
You have a race condition. the s.send('die') may not get there before
the close call. The close() call (IIRC Python does not change the
semntic) closes for both send and recv, and recv after close generates
a reset.
Also, since you have nothing there to consume the die message, it may
be possible that calling close with data in the socket triggers ReSeT
but on that one I am not so sure.
> Thanks,
> -Jonathan
> ---- code follows ----
> #!/usr/bin/python
> import socket, threading, time
--
portable adj, code that compiles under more than one compiler
these opinions are mine, all mine; HP might not want them anyway... :)
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
No, that's not it. The exception is always thrown during the recv, not
the send. (You could also add additional sleeps to force any
particular sequence, but as long as you have the send before the close,
and the close before recv finishes, you will get the reset error.)
> Also, since you have nothing there to consume the die message, it may
> be possible that calling close with data in the socket triggers ReSeT
> but on that one I am not so sure.
Hmm. Maybe that's the problem. Any idea where I could find a
definitive statement on this?
-Jonathan
>>Also, since you have nothing there to consume the die message, it may
>>be possible that calling close with data in the socket triggers ReSeT
>>but on that one I am not so sure.
>
> Hmm. Maybe that's the problem. Any idea where I could find a
> definitive statement on this?
Closing before all the data has been received definitely causes the
receiver of the unread data to issue a reset. See Stevens TCP/IP
Illustrated passim, also a note in Sun's Java Networking Guide to
Features,
http://java.sun.com/j2se/1.5.0/docs/guide/net/articles/connection_release.html
Thank you very much for clearing that up for me.
-Jonathan