Code run from IDLE but not via double-clicking on its *.py

Bryan Olson fakeaddress at nowhere.org
Fri Sep 2 18:09:05 CEST 2005


Dennis Lee Bieber wrote:
 > 	I'm going to go back a few messages... Looking for a
 > simplification...
[...]
 > 	TWO threads, both just infinite loops of the same nature (you could
 > actually have done ONE def and passed different arguments in to
 > differentiate the two thread invocations.
 >
 > 	However, threads aren't really needed for this simple connection
 > relay...

True, though I prefer the tread solution. You can see my exmaple
in message <QcQRe.637$XY7.275 at newssvr11.news.prodigy.com>.

   http://groups.google.com/group/comp.lang.python/msg/ffd0159eb52c1b49


 > The following has /not/ been run (since I don't have your
 > server nor VBS) but should do about the same thing (see comments for one
 > lack).

There's an easy trick to pseudo-test such a thing: for the
server host and port, edit in 'www.yahoo.com' and 80. Then
direct a browser to http://localhost:1434.


 > =======>	Suggested code

I have a few further suggestions.

[...]
 > DBMSSocket.connect((host, DBMSPort))
 >
 > MySocket.bind((host, MyPort))

I'd definitely wait for the client connection to come in, before
making the server connection.


 > MySocket.listen(1)
 >
 > Client, Addr = MySocket.accept()
 >
 > while True:
 >     #   wait for either connection to have readable data
 >     (inbound, outbound, excption) = select.select([DBMSSocket, 
Client], [], [])

One trick I used was to pass a timeout parameter; I used one
second. Python (at least my version on WinXP) won't honor the
keyboard interrupt while waiting at the select. The select is in
an infinite loop anyway, so it just means polling for a keyboard
interrupt every second.


 >     #   handle each readable socket
 >     #   NOTE: there is no way (in this quick and dirty code) to
 >     #       detect end of connections.
 >     #       probably need to do things with the excption list --
 >     #       passing in the sockets, and closing them when they
 >     #       show up in excption -- actually, if one side closes
 >     #       there is no reason to continue processing the other
 >     #       side, so on any excption, could close both and exit

Not really. If the remote side shuts down writing, the socket
will select as readable, and read will return the empty string.
That's the documented method to detect when the remote side is
done writing. When it happens, you should send the shutdown
across, much like you copy data across: shutdown writing on the
other socket. To terminate clean, copy all data and both
shutdowns (though the latter shutdown should happen
automatically if you just let the socket be destructed).

 >         data = s.recv(4096)
 >         if s is Client:
 >             print "From VBS: ",
 >             MyDBMS.send(data)

Use sendall() in place of send(); same for the other call to
socket.send(). It's an evil trap: under most circumstances,
send() will send all the data, but it's not guaranteed to do so.
With a size of 4096, you're probably O.K., but technically it's
a bug. (The slicker-than-needed thing to do would be to test
whether the outgoing socket is writable within the select, then
send() as much as you can, and keep selecting and sending until
all the data is out.)


-- 
--Bryan



More information about the Python-list mailing list