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

N

n00m

LOL... seems it disappears only in Win98. In Win2k it goes like this:

C:\>d:
D:\>python23\python d:\python23\socket6.py
D:\>

C:\> d:
D:\> cd \python23
D:\> python d:\python23\socket6.py > out.txt 2> err.txt
Does anything appear in d:\python23\out.txt or d:\python23\err.txt?
NOTHING APPEARED IN THEM.
n00m, can you post the vbs?

Set cn = CreateObject("ADODB.Connection")
cn.Open _
"Provider=sqloledb;Data Source=192.168.0.3,1434;" & _
"Network Library=DBMSSOCN;Initial Catalog=pubs;" & _
"User ID=qwe;Password=asdasd;"
cn.Execute "select top 1 * from authors;"
cn.Close
Set cn = Nothing
 
N

n00m

Dennis:
However, threads aren't really needed for this simple connection
relay... 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).

To some degree you are right!
If the vbs issues only some "primitive" sql commands, like

select au_fname from authors where zip=678678678
(the authors is a table in the pubs database in SQL Server)

then it works even without threading it.
But if the vbs issues e.g. this command for sql server:

"waitfor delay '000:00:05'; raiserror ('AAA',10,1) with nowait;"

then things go messed and confused...
and the code refuses to work in only one (main) thread.
In short, see this my topic on an sql server forum:

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=48619

Btw, I have NOT yet seen any WORKING C# code for my subject.
 
B

Bryan Olson

Dennis said:
> 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 <[email protected]>.

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.)
 
D

Dennis Lee Bieber

But if the vbs issues e.g. this command for sql server:

"waitfor delay '000:00:05'; raiserror ('AAA',10,1) with nowait;"

then things go messed and confused...

Hope you'll forgive my comment -- but for some reason those look
like they were meant more for use within a stored procedure than direct
invocation...
and the code refuses to work in only one (main) thread.
In short, see this my topic on an sql server forum:

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=48619

Don't know if it applies, but the code I see there is not only
single-threaded, but is forcing the two sockets to operate in lock-step:

wait for VBS
send to server
wait for server
send to VBS
repeat

Something that could easily break under a few scenarios... One is if
a socket transaction isn't complete (TCP/IP does not guarantee that what
is sent as one packet is received as one packet, and vice versa). You
could get a situation where you've relayed an incomplete command to the
server, and the server doesn't send anything back until it receives the
rest of the command -- so you deadlock waiting for a server that is
still waiting for you. Another could be that those individual statements
in (each ;) could generate separate server response strings, but you've
read the first response and have gone back to waiting for the VBS,
without processing delayed response packets from the server.

My version, using select(), shouldn't have this problem. Regardless
of what any individual packet contained, if /either/ socket has more
data, it will be read and transferred. [Of course, you then have the
problem of the VBS maybe not handling fragmented responses properly]

--
 
N

n00m

Dennis said:
Hope you'll forgive my comment -- but for some reason those look...
Your comments are absolutely relevant.
My version, using select(), shouldn't have this problem.
Now I see what you meant ("You need no threads"). Your code works just
fine (hope over LAN too). I corrected a couple of typos in it.
 
D

Dennis Lee Bieber

Dennis Lee Bieber wrote:
Now I see what you meant ("You need no threads"). Your code works just
fine (hope over LAN too). I corrected a couple of typos in it.

As mentioned, since I didn't have the VBS or server, I only coded
from the help system -- I could not test run my code. And, as mentioned,
I did not include logic to handle a clean shut-down.
--
 
D

Dennis Lee Bieber

I have a few further suggestions.
I have very little actual experience in socket programming... Just
enough to know some of the pitfalls (fragmented packets, for example;
select on windows only works for sockets while UNIX/Linux can mix
sockets and files)...
--
 
N

n00m

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

It still does not work. Weird.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,264
Messages
2,571,315
Members
48,000
Latest member
SusannahSt

Latest Threads

Top