[Pythonmac-SIG] Solved: problem with socket library in 2.0?
James B. Wilkinson
jimmy@CS.cofc.EDU
Sat, 3 Feb 2001 19:51:36 -0500
> > I found the answer in the socket HowTo, which I didn't know about
>> until I saw one of my students reading it this afternoon. I was using
>> '127.0.0.1' as the address of the server socket, thereby rendering it
>> invisible to other machines.
>>
>> This is new in 2.0. Is this another one of those cases where the
>> behavior in 1.5.2 was convenient but incorrect?
>
>The old behaviour was probably because Python 1.5.2 used GUSI 1 for socket
>I/O, which was implemented with MacTCP, which didn't understand about multiple
>network addresses per machine, so a listen() ignored the source IP address.
>
>Python 2 uses GUSI 2 which is implemented with Open Transport, which does know
>about multihoming, so the source IP address is suddenly important.
>
>Note that the normal way to do a listen(), on both 1.5.2 and 2.0, is not to
>pass any source IP address at all, in which case the listen() will happen on
>all IP addresses of the machine automatically.
>--
>Jack Jansen | ++++ stop the execution of Mumia Abu-Jamal ++++
>Jack.Jansen@oratrix.com | ++++ if you agree copy these lines to your sig ++++
>www.oratrix.nl/~jack | see http://www.xs4all.nl/~tank/spg-l/sigaction.htm
Do you mean to use '' instead of gethostname() in the bind() call?
Yes, that works. I had a student tell me that it no longer works in
version 2.0. Should have known not to believe him.
In checking all this out, I noticed an apparent change in behavior in
the example at
http://www.python.org/doc/current/lib/socket-example.html On closer
inspection it seemed not to be a change at all, just a clearer report
of what happened. I guess that's also because of GUSI2. Here's the
code.
#Stream Server
from socket import *
HOST = ''
PORT = 50007
s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data: break
conn.send(data)
conn.close()
If I run the server in 1.5.2 and hit it with the client in the same
example, I get the 'Connected by' message, and then Python
terminates. In 2.0 it complains as follows before terminating:
"socket.error: (57, 'Socket is not connected')". Now I understand
what's going on here, I think. The call to conn.recv(1024) is a
*blocking* call, and in this simple program, the only way out of the
loop is for the client to quit and close its end of the socket. GUSI1
seems to do the same thing, but, without the error message, it looked
like a nonblocking call which terminated the loop on the second pass
by returning 0 bytes of data. If I'm right about that, then the "if
not data: break" line is superfluous. Just now I commented it out,
expecting the program to behave just as it did before. Well,
surprise. In 2.0 that's the case, but in 1.5.2 it does just exactly
the same as in 2.0, same error message and all. Wait, not *exactly*
the same. In 2.0 the error is associated with the conn.recv() call;
in 1.5.2, it's associated with the conn.send() call.
So the truth seems to be that the conn.recv() always blocked (a
sleep(5) in front of the close() in the client proves that). However,
in 1.5.2 once the connection is broken, it returns with 0 bytes of
data, whereas in 2.0 it gives an error.
If I run the server on Windows and hit it with the client, I never
get the error. It acts like 1.5.2 on the Mac. *Unless* I comment out
the "if not data: break" line. In that case the server simply hangs.
That's exactly the same thing I get running the server on Linux, but
the Linux box has Python 1.5. So I build 2.0 on the Linux box, and
it's the same.
By this time I'm very confused, but it seems safe to say that, in
this respect, 2.0 does not behave the same on Macs as it does on
Linux and Windows.
--
-------------------------------------------------------------
Jimmy Wilkinson | Perfesser of Computer Science
jimmy@cs.CofC.edu | The College of Charleston
(843) 953-8160 | Charleston SC 29424
If there is one word to describe me,
that word would have to be "profectionist".
Any form of incompitence is an athema to me.