By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,101 Members | 1,463 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,101 IT Pros & Developers. It's quick & easy.

Sockets: code works locally but fails over LAN

P: n/a
import socket, thread
host, port = '192.168.0.3', 1434
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((host, 1433))
s1.bind((host, port))
s1.listen(1)
cn, addr = s1.accept()

def VB_SCRIPT():
while 1:
data = cn.recv(4096)
if not data: return
s2.send(data)
print 'VB_SCRIPT:' + data + '\n\n'

def SQL_SERVER():
while 1:
data = s2.recv(4096)
if not data: return
cn.send(data)
print 'SQL_SERVER:' + data + '\n\n'

thread.start_new_thread(VB_SCRIPT,())
thread.start_new_thread(SQL_SERVER,())

=============================================

The above code acts as an intermediator between a very simple VB script
and SQL Server. Like follows:
the vbs sends its requests to "fake" port 1434 and the python code
catches and re-sends them to sql server which listens to its DEFAULT
port = 1433... And vice versa.
================================================== =======
VB script:
================================================== =======

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 * from authors;"
cn.Close
Set cn = Nothing

================================================== =======
It works fine (I see all client/server data printed in IDLE window)but
only locally. I.e. if vbs, python and sql server run on the same
machine.

If I run the vbs from some other machine in my LAN then it fails to
work out properly. Below is all that vbs and sql server are able to say
to each other:
================================================== =========

VB_SCRIPT:
   SERVER qwe asdasd 000000a5 *·€Ut
 Microsoft (r) W 192.168.0.3,1434  asdasd
 OLEDB 


SQL_SERVER:
 Щ 3 г
pubsmaster«0 E  # Changed database context
to 'pubs'.W г

us_english «4 G  ' Changed language setting to us_english.W г
cp1251 *  Microsoft SQL Server _ Вг 40964096э
VB_SCRIPT:
 G   4096 

================================================== ========
In abt 30 seconds OLE DB Provider (on the vbs side) reports "General
Network Error".
PEOPLE, WHY ON THE EARTH IT DOES NOT WORK OVER LAN ???

PS:
Of course, without involving Python into the process vbs and sql server
communicate with each other just fine - no matter locally or over LAN;
on win2k machines or on/from NT 4.0 machine.

Aug 31 '05 #1
Share this Question
Share on Google+
33 Replies


P: n/a
n00m wrote:
import socket, thread
host, port = '192.168.0.3', 1434
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((host, 1433))
s1.bind((host, port))
s1.listen(1)
cn, addr = s1.accept()

def VB_SCRIPT():
while 1:
data = cn.recv(4096)
if not data: return
s2.send(data)
print 'VB_SCRIPT:' + data + '\n\n'

def SQL_SERVER():
while 1:
data = s2.recv(4096)
if not data: return
cn.send(data)
print 'SQL_SERVER:' + data + '\n\n'


Several suggestions:

1. Use repr(data) instead of just 'data' above, to see better the actual
bytes without the possibility of control characters like \r and \b
screwing things up.

2. I'm not at all sure that accessing the same socket object
simultaneously from two threads is safe. You might consider creating a
pair of Queue objects to safely communicate the information between the
two threads. That, of course, poses the problem of how do you wait on
data to arrive from the socket and from the Queue at the same time. One
approach is to use non-blocking sockets or timeouts, while the other is
to use a pre-existing asynchronous framework such as, say, Twisted, and
avoid reinventing the wheel (and making all the same mistakes that other
programmers have made zillions of times before you).

It's also possible this is not remotely related to your problem, but I
suspect without knowing more about SQL Server, VB, and your own setup
I'd be guessing wildly anyway...

-Peter
Aug 31 '05 #2

P: n/a
On 2005-08-31, Peter Hansen <pe***@engcorp.com> wrote:
2. I'm not at all sure that accessing the same socket object
simultaneously from two threads is safe.


It's OK under Unix. Having one thread handle rx and a
different one handle tx is a pretty widely used method.

Don't know about Win32...
--
Grant Edwards grante Yow! Someone in DAYTON,
at Ohio is selling USED
visi.com CARPETS to a SERBO-CROATIAN
Aug 31 '05 #3

P: n/a
Thank you all for your replies!
1.
repr() is not what I need (currently).
I'd better like to see the pure text of "talkings" between VBS and SQL
Server.
2.
Jp, thank you very much for the links!
I just oblige to test this Twisted stuff, but I'm afraid it's a bit
above my head
so far.
And, frankly speaking, above all I'd like to understand why my code
only works
locally... I wish it did not work AT ALL. Sure you understand what I
mean. :)

Aug 31 '05 #4

P: n/a
Grant Edwards wrote:
Peter Hansen wrote:

2. I'm not at all sure that accessing the same socket object
simultaneously from two threads is safe.


It's OK under Unix. Having one thread handle rx and a
different one handle tx is a pretty widely used method.

Don't know about Win32...


A thread for send and one for recv is also frequently used with
Winsock. Can anyone vouch for the Python wrapping?
--
--Bryan
Aug 31 '05 #5

P: n/a
On 2005-08-31, Bryan Olson <fa*********@nowhere.org> wrote:
2. I'm not at all sure that accessing the same socket object
simultaneously from two threads is safe.


It's OK under Unix. Having one thread handle rx and a
different one handle tx is a pretty widely used method.

Don't know about Win32...


A thread for send and one for recv is also frequently used
with Winsock. Can anyone vouch for the Python wrapping?


The last time I looked, it was a pretty thin wrapper, and
shouldn't cause a problem. I just looked at 2.3.5 sources. [I
think the timeout feature is new since I hacked on socketmodule.c
last.] I don't really see anything troublesome.

Basically, socket.recv() just calls recv() and socket.send()
just calls send().

--
Grant Edwards grante Yow! MY income is ALL
at disposable!
visi.com
Aug 31 '05 #6

P: n/a

n00m wrote:
import socket, thread
host, port = '192.168.0.3', 1434
Consider using INADDR_ANY instead of the specific host IP
address. The empty string will resolve to INADDR_ANY if passed
as the host to bind(). (Though that's not the problem.)
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((host, 1433))
s1.bind((host, port))
s1.listen(1)
cn, addr = s1.accept()
You probably want the the accept() in a loop.

def VB_SCRIPT():
while 1:
data = cn.recv(4096)
if not data: return
s2.send(data)
Use sendall(), not send().
print 'VB_SCRIPT:' + data + '\n\n'

def SQL_SERVER():
while 1:
data = s2.recv(4096)
if not data: return
cn.send(data)
As above, use sendall().
print 'SQL_SERVER:' + data + '\n\n'

thread.start_new_thread(VB_SCRIPT,())
thread.start_new_thread(SQL_SERVER,())

=============================================

The above code acts as an intermediator between a very simple VB script
and SQL Server. Like follows:
the vbs sends its requests to "fake" port 1434 and the python code
catches and re-sends them to sql server which listens to its DEFAULT
port = 1433... And vice versa. [...] It works fine (I see all client/server data printed in IDLE window)but
only locally. I.e. if vbs, python and sql server run on the same
machine.

[...]
My first two guess are:

The client is trying to make more than one connection.
Putting accept in a loop and moving some stuff will support
that.

The send() call is not sending all the data. Using sendall()
should fix that.
Try the following, but *not in Idle*. The code doesn't yet have
a clean stopping method, and the run-on threads will screw-up
Idle.

import socket, thread

sqls_host, sqls_port = '192.168.0.3', 1443
proxy_host, proxy_port = '', 1434

# How I tested it:
# sqls_host, sqls_port = 'www.google.com', 80
def VB_SCRIPT():
while 1:
data = cn.recv(4096)
if not data: return
s2.sendall(data)
print 'VB_SCRIPT:' + data + '\n\n'

def SQL_SERVER():
while 1:
data = s2.recv(4096)
if not data: return
cn.sendall(data)
print 'SQL_SERVER:' + data + '\n\n'
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.bind((proxy_host, proxy_port))
s1.listen(5)

while 1:
cn, addr = s1.accept()
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((sqls_host, sqls_port))
thread.start_new_thread(VB_SCRIPT,())
thread.start_new_thread(SQL_SERVER,())


--
--Bryan
Aug 31 '05 #7

P: n/a
On 31 Aug 2005 10:43:01 -0700, "n00m" <n0**@narod.ru> declaimed the
following in comp.lang.python:
Thank you all for your replies!
1.
repr() is not what I need (currently).
I'd better like to see the pure text of "talkings" between VBS and SQL
Server.
repr() shows everything -- including the values of any "non
printable" characters.
print x This is
strangely spaced? print repr(x) 'This is \nstrangely\tspaced\x03'
Note that without the repr() you can't tell that the "spaces" in the
second line are the result of a single <tab>, nor that there are a lot
of spaces following the "is". And the last character (displays as a ?
here, shows up as a HEART on the command console) is a <ctrl-c>.

"x" was created using:
x = "This is \nstrangely\tspaced\x03"


-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Sep 1 '05 #8

P: n/a
"n00m" <n0**@narod.ru> wrote:
PEOPLE, WHY ON THE EARTH IT DOES NOT WORK OVER LAN ???


what happens if you change

s1.bind((host, port))

to

s1.bind(("", port))

?

</F>

Sep 1 '05 #9

P: n/a
* n00m <n0**@narod.ru> [2005-08-31 05:45]:
import socket, thread
host, port = '192.168.0.3', 1434
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((host, 1433))
s1.bind((host, port))


I think the problem is that you're using the same host for both the send
and recieve sockets. Wouldn't you want one host to be the localhost,
and one to be sql server?

If it doesn't work even when only the VBscript is on a different box,
are you running an OS with a firewall that you have to disable?

-John
Sep 1 '05 #10

P: n/a
>Bryan;
I tested your code locally (in I*D*L*E) - it works fine!
And of course I'll test it over LAN but only tomorrow - at work.
See the picture of my IDLE window with output of your code:
http://free.7host02.com/n00b/socket_Br.gif
Note the 4th line in Blue: there Z is the name of my home machine,
qwe is the login name (from VBS(ADO) connection string) and right
after "qwe" - this login's password ("asdasd") but it's encrypted
by oledb provider.

Dennis; I understand pretty well what you mean. Thank you for the repr().

Fredrik; Locally it works! The rest - tomorrow.

John;

How exactly should I "correct" the code?

Sep 1 '05 #11

P: n/a
n00m wrote:
Bryan;
I tested your code locally (in I*D*L*E) - it works fine!


Glad it worked, but I'd still disrecommend IDLE for that
version. Threads may live after the program seems to be done
(and may still own the port you need). Below is a version that
respects ^C to terminate more-or-less cleanly.
And of course I'll test it over LAN but only tomorrow - at work.
See the picture of my IDLE window with output of your code:
http://free.7host02.com/n00b/socket_Br.gif


I didn't touch the printing, so it should output the same thing
as your version. Looks like you've got some UTF-16 action there,
and Python may be able to print it nicer if you use the
unicode/codec stuff.
--
--Bryan
import socket, threading, select

sqls_host, sqls_port = '192.168.0.3', 1443
proxy_host, proxy_port = '', 1434
def start_deamon_thread(func, args):
""" Run func(*args) in a deamon thread.
"""
thread = threading.Thread(target=func, args=args)
thread.setDaemon(True)
thread.start()
def sock_copy(s_from, s_to, annotation):
while 1:
data = s_from.recv(4096)
if not data:
break
s_to.sendall(data)
print annotation + data + '\n\n'
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.bind((proxy_host, proxy_port))
s1.listen(5)

while 1:
s, _, _ = select.select([s1], [], [], 1.0)
if s:
cn, _ = s1.accept()
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((sqls_host, sqls_port))
start_deamon_thread(sock_copy, (cn, s2, 'VB_SCRIPT:'))
start_deamon_thread(sock_copy, (s2, cn, 'SQL_SERVER:'))
Sep 2 '05 #12

P: n/a
On 1 Sep 2005 10:51:32 -0700, "n00m" <n0**@narod.ru> declaimed the
following in comp.lang.python:
Bryan; I tested your code locally (in I*D*L*E) - it works fine!
And of course I'll test it over LAN but only tomorrow - at work.
See the picture of my IDLE window with output of your code:
http://free.7host02.com/n00b/socket_Br.gif
Note the 4th line in Blue: there Z is the name of my home machine,
qwe is the login name (from VBS(ADO) connection string) and right
after "qwe" - this login's password ("asdasd") but it's encrypted
by oledb provider.

Dennis;

I understand pretty well what you mean. Thank you for the repr().

Your screen capture would be a lot easier to read if it had been
used... We'd see what all those boxes are hiding (Offhand, I'd suspect
unicode string data, the way recognizable words are being spaced...)
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Sep 2 '05 #13

P: n/a
I wrote:
Below is a version that respects ^C to terminate
more-or-less cleanly.
Oops, one more bug^H^H^H improvement. I forgot to shutdown
writing.

import socket, threading, select

sqls_host, sqls_port = '192.168.0.3', 1443
proxy_host, proxy_port = '', 1434
def start_deamon_thread(func, args):
""" Run func(*args) in a deamon thread.
"""
thread = threading.Thread(target=func, args=args)
thread.setDaemon(True)
thread.start()
def sock_copy(s_from, s_to, annotation):
while 1:
data = s_from.recv(4096)
if not data:
Insert:
| s_to.shutdown(socket.SHUT_WR)
break
s_to.sendall(data)
print annotation + data + '\n\n'
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.bind((proxy_host, proxy_port))
s1.listen(5)

while 1:
s, _, _ = select.select([s1], [], [], 1.0)
if s:
cn, _ = s1.accept()
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((sqls_host, sqls_port))
start_deamon_thread(sock_copy, (cn, s2, 'VB_SCRIPT:'))
start_deamon_thread(sock_copy, (s2, cn, 'SQL_SERVER:'))

--
--Bryan
Sep 2 '05 #14

P: n/a
My today's tests (over LAN).
I think *it* will drive me mad very soon.

Firstly I tested both Bryan's codes. And they worked fine!
Just as if they were tested locally!

Then I tested Fredrik suggestion. And it worked out too.
Expect unexpected, - as they say.

At last I decided to test my own version (just for the
experiment's purity). And... pfffff... it worked OK!

What happened to those machines over the night?
NOTHING! Nobody can access them but me.

Then I decided to test it from other ("the third") machine.
And again both Bryan's codes worked out like champs.
But my own ... failed! (as usually)!

Then I ran the vbs from the 4th machine...
Bryan's and *mine* worked OK...
Bryan wrote:
The client is trying to make more than one connection. I don't think so. Look at the very first line of the vbs:

Set cn = CreateObject("ADODB.Connection")

Create .Connection! NOT .Connections.
Glad it worked, but I'd still disrecommend IDLE... But it does NOT work without IDLE!

PS: Oops, one more bug^H^H^H improvement.
I forgot to shutdown writing.

LOL Thank you! But while I don't understand what's going on
with the core part of the code this improvement doesn't much
matter.

Sep 2 '05 #15

P: n/a
n00m wrote:
My today's tests (over LAN).
I think *it* will drive me mad very soon.
<Conflicting results snipped>

Network programming is like that. Just because something worked
once doesn't mean it really works. I had guessed two causes for
the behavior you were seeing, and either could result in sporadic
failures.
Bryan wrote:
The client is trying to make more than one connection.
I don't think so. Look at the very first line of the vbs:

Set cn = CreateObject("ADODB.Connection")

Create .Connection! NOT .Connections.


An ADODB connection is not the same as a TCP connection; unless
you have a documented promise, don't expect them to map one-to-
one. I don't know much about ADODB, but it's perfectly normal in
network programming to run multiple logical connections over one
TCP connection, or use multiple TCP connections to carry one
logical connection, or both at the same time.
Glad it worked, but I'd still disrecommend IDLE...


But it does NOT work without IDLE!


Odd. What happens if you run it from a command line?

[...] But while I don't understand what's going on
with the core part of the code this improvement doesn't much
matter.


Do you want to be a network engineer? What's going on is too
many unsafe assumptions, and isolating the one (or ones) biting
you could take a lot of your time. My last version, with the
shutdown fix, is a pretty general TCP spy-proxy. The printing is
a bit dodgy, but other than that, I don't think it assumes
anything that TCP doesn't guarantee. (But don't let it walk
alone in crime-ridden neighborhoods such as the Internet.)
--
--Bryan
Sep 2 '05 #16

P: n/a
On 2 Sep 2005 10:21:03 -0700, "n00m" <n0**@narod.ru> declaimed the
following in comp.lang.python:
My today's tests (over LAN).
I think *it* will drive me mad very soon.
If going over a LAN, you have more things to consider.

1) are there any firewalls that might block a connection (in either
direction)

2) could the DBMS privilege tables be set up to reject connections
and/or commands from certain machines
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Sep 3 '05 #17

P: n/a
Bryan wrote:
Do you want to be a network engineer? lol... definetely not! It's just my curiosity.
At my work my tools are: vba, vbs, jet-sql (ms access),
t-sql (ms sql server). The pretty humble set.
My first two guess are:
The client is trying to make more than one connection.
Putting accept in a loop and moving some stuff will support
that. BUT your *1st version* does NOT support more than ONE client's
connection! How do I know that? I just ran several (3) instances
of my.vbs (almost) simultaneously and only the first of them could
connect to SQL Server via Python!
Just in case: SQL Server itself can accept up to 32767 clients.

Then (if I'm not wrong here) what's the difference with my own
version? Maybe replacing send() with sendall() will be quite enough
to make it working over LAN? I've NOT tested this!

PS Yes! Your last version works like a champ. It easily handles up
to 5 instances of my.vbs! Except of this thing: AttributeError: 'module' object has no attribute 'SHUT_WR'

Seems it's a pure Unix constant.
But it does NOT work without IDLE!

Odd. What happens if you run it from a command line?

In a moment - AFTER I start my.vbs - in console window new prompt
"D:\>" appears... and vbs reports "General Network Error".

Dennis;
No no no! It's NOT firewalls trick. It's NOT db permissions issue.
VBS and SQL Server work with each other ABSOLUTELY FINE - from ANY
machine at ANY time at ANY free port - BUT WITHOUT Python being a
mediator for them.

Sep 3 '05 #18

P: n/a
n00m wrote:
Your last version works like a champ. It easily handles up
to 5 instances of my.vbs! Except of this thing:
AttributeError: 'module' object has no attribute 'SHUT_WR'


Seems it's a pure Unix constant.


No, my guess is that you're running an old version of Python.
The constant was added in the source on 27 Nov 2003; I'm not
sure what version that would first appear in. You can fix it
either by upgrading your Python distribution (a good idea
anyway), or replacing:

sock.shutdown(socket.SHUT_WR)

with:

sock.shutdown(1)

But it does NOT work without IDLE!


Odd. What happens if you run it from a command line?


In a moment - AFTER I start my.vbs - in console window new prompt
"D:\>" appears... and vbs reports "General Network Error".


Hmmm... not much to go on there. I tested it on Win-XP, running
it from a command line. I set the server to ('www.googl.com',
80), and I was able to web-search through it.

Are you running XP's local firewall?
--
--Bryan
Sep 3 '05 #19

P: n/a
n00m wrote:
Bryan wrote:
PS Yes! Your last version works like a champ. It easily handles up
to 5 instances of my.vbs! Except of this thing:
AttributeError: 'module' object has no attribute 'SHUT_WR'


Seems it's a pure Unix constant.


Definitely not. Are you sure you've got a proper Python install?

c:\>python
Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on
win32
import socket
dir(socket) ['AF_APPLETALK', 'AF_DECnet', ... 'SHUT_RD', 'SHUT_RDWR', 'SHUT_WR',
'SOCK_DGRAM', ... 'sys', 'timeout']
socket.SHUT_WR

1

If you're really getting this error it would seem something is very
wrong on your machine.

-Peter
Sep 3 '05 #20

P: n/a
1.
Python 2.3.4

2.
Win98 and Win2k Professional

Sep 3 '05 #21

P: n/a
On Sat, 03 Sep 2005 20:20:31 GMT, Bryan Olson <fa*********@nowhere.org>
declaimed the following in comp.lang.python:

No, my guess is that you're running an old version of Python.
The constant was added in the source on 27 Nov 2003; I'm not
Are you sure of that 2003?

C:\Documents and Settings\Dennis Lee Bieber>python
ActivePython 2.3.5 Build 236 (ActiveState Corp.) based on
Python 2.3.5 (#62, Feb 9 2005, 16:17:08) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
import socket
socket.SHUT_WR

Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'module' object has no attribute 'SHUT_WR'

Would appear to be new with 2.4.x (I believe the reason I'm still on
2.3.x is that Plone didn't like 2.4.x and I couldn't seem to find a
compatible set of paths to have Plone work with its Python without
conflicting with a separate ActiveState install. As it is, it took some
games to get AS into the Plone directory.)
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Sep 3 '05 #22

P: n/a
Dennis Lee Bieber wrote:
Bryan Olson declaimed the following in comp.lang.python:
No, my guess is that you're running an old version of Python.
The constant was added in the source on 27 Nov 2003; I'm not

Are you sure of that 2003?


Yes, but that's when it went into the source, in the sense of
first being edited into a file. It was Revision 1.279 of
socketmodule.c.

http://cvs.sourceforge.net/viewcvs.p...1.312&view=log
--
--Bryan
Sep 3 '05 #23

P: n/a
Bryan;
Look at how I corrected your the very first version
(see added arguments in both functions). And now it
really can handle multiple connections!
import socket, thread

sqls_host, sqls_port = '127.0.0.1', 1433
proxy_host, proxy_port = '127.0.0.1', 1434

# How I tested it:
# sqls_host, sqls_port = 'www.google.com', 80

def VB_SCRIPT(s2, cn):
while 1:
data = cn.recv(4096)
if not data: return
s2.sendall(data)
print 'VB_SCRIPT:' + data + '\n'

def SQL_SERVER(s2, cn):
while 1:
data = s2.recv(4096)
if not data: return
cn.sendall(data)
print 'SQL_SERVER:' + data + '\n'

s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.bind((proxy_host, proxy_port))
s1.listen(5)

while 1:
cn, addr = s1.accept()
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((sqls_host, sqls_port))
thread.start_new_thread(VB_SCRIPT,(s2, cn))
thread.start_new_thread(SQL_SERVER,(s2, cn))
Without these corrections I got these error messages
when I launched SIMULTANEOUSLY 3 instances of my.vbs:
Unhandled exception in thread started by
Unhandled exception in thread started by
Traceback (most recent call last):
Traceback (most recent call last):
File "D:\Python23\00\socket_Br10.py", line 18, in SQL_SERVER
File "D:\Python23\00\socket_Br10.py", line 13, in VB_SCRIPT
data = s2.recv(4096)
s2.sendall(data)
socket File "<string>", line 1, in sendall
..socketerror.: error: (10054, 'Connection reset by peer')
(10054, 'Connection reset by peer')

Sep 3 '05 #24

P: n/a
n00m wrote:
Bryan;
Look at how I corrected your the very first version
(see added arguments in both functions). And now it
really can handle multiple connections!


Ah, yes, I see. (In my defense, I had already fixed that bug in
my second version.)
--
--Bryan
Sep 4 '05 #25

P: n/a
Bryan Olson wrote:
Ah, yes, I see. (In my defense, I had already fixed that bug in
my second version.)

1.
Yes! I myself noticed that, but your 2nd version looks
a bit more verbose.
2.
This all means... what? ONLY send() vs sendall() matters?
Sometimes send() really sends ALL and my version works too!
I must give it a thorough testing!
3.
See how it looks in SQL Server Profiler (it's its utility for
tracing client/server events) WHEN I started 5 copies of .vbs.
http://free.7host02.com/n00b/SQL_Profiler.gif

Btw, without s2.shutdown(1) those vbs' do NOT disconnect from
the server (see DISCONNECT events on the gif).
The latest python version:
==============================
import socket, thread

sqls_host, sqls_port = '127.0.0.1', 1433
proxy_host, proxy_port = '127.0.0.1', 1434

# How I tested it:
# sqls_host, sqls_port = 'www.google.com', 80

def VB_SCRIPT(s2, cn):
while 1:
data = cn.recv(4096)
if not data:
s2.shutdown(1)
return
s2.sendall(data)
print 'VB_SCRIPT:' + data + '\n'

def SQL_SERVER(s2, cn):
while 1:
data = s2.recv(4096)
if not data: return
cn.sendall(data)
print 'SQL_SERVER:' + data + '\n'

s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.bind((proxy_host, proxy_port))
s1.listen(5)

while 1:
cn, addr = s1.accept()
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((sqls_host, sqls_port))
thread.start_new_thread(VB_SCRIPT,(s2, cn))
thread.start_new_thread(SQL_SERVER,(s2, cn))
The vbs text:
==============
Set cn = CreateObject("ADODB.Connection")
cn.Open _
"Provider=sqloledb;Data Source=127.0.0.1,1434;" & _
"Network Library=DBMSSOCN;Initial Catalog=pubs;" & _
"User ID=qwe;Password=asdasd;"
cn.Execute _
"select 'AAAAAAAAAAAAAAA';" & _
"waitfor delay '00:00:02'; raiserror('XXX',10,1) with nowait;" & _
"waitfor delay '00:00:02'; raiserror('YYY',10,1) with nowait;" & _
"waitfor delay '00:00:02'; raiserror('ZZZ',10,1) with nowait;" & _
"select 'BBBBBBBBBBBBBBB';"
cn.Close
Set cn = Nothing

Sep 4 '05 #26

P: n/a

Newbie question:

I have a dictionary called "rec". And a list called "db". db is my
database. rec are to be records in the database. In a loop I'm trying to
create a record and add it to my database. The key stmt is

db.append( rec )

This works initially but it seems that instead of copying the values in
rec and adding it to db, only a reference of rec is added to db. Thus
when I reassign rec with new data and then do another append I end up
with two records in my database but now the both contain the same data,
namely the latest version or rec.

So how do I add a dictionary into a list by value rather than by reference?

The complete code is here:

================================================== =======
#!/usr/bin/python

import sys

inputfile = sys.argv[1]

keywords = [ 'place-name=',
'addr-line1=',
'addr-line2=',
'addr-city=',
'addr-state=',
'addr-country=',
'addr-postalcode=',
'mailaddr-line1=',
'mailaddr-line2=',
'mailaddr-city=',
'mailaddr-state=',
'mailaddr-country=',
'mailaddr-postalcode=',
'place-phone1=',
'place-phone2=',
'place-fax=',
'place-email1=',
'place-email2=' ]

def csv_it():
db = [] # the entire database of records
rec = {} # a single rec: a dictionary of field names and data pairs
fields = [] # list of field names collected so far for current record
for line in open(inputfile):
kword = getkeyword(line) # get keyword (or field name)
if kword:
# We've got a line with a keyword in it
if kword == keywords[0]:
# Starting a new record, so save current record
db.append( rec )
printdb(db, "stage 1")

# Now clear current record
fields = []
rec.clear()
dummylist = []
for i in range(1,len(keywords)+1):
dummylist.append('')
for k,d in zip(keywords,dummylist):
rec[k] = d
printdb(db, "stage 2")

# make sure we are not encountering a duplicate key word
if kword in fields:
print "Record contains duplicate field"
print line,
sys.exit()
fields.append(kword)
# collect our data and store it in the current record
data = line[line.find('=')+1:]
datalstrip = data.lstrip()
datarstrip = datalstrip.rstrip()
rec[kword] = datarstrip

printdb(db,"stage 3")
db.append( rec ) # don't forget whatever we have in our last record

# dump the database in comma separated value form
outstring = ''
for k in keywords:
outstring += '"'
outstring += k
outstring += '"'
outstring += ','
print outstring
for r in db:
outstring = ''
for k in keywords:
if r[k]:
outstring += '"'
outstring += r[k]
outstring += '"'
outstring += ','
print outstring
def getkeyword(line):
equal_index = line.find('=')
if equal_index >= 0:
kword = line[0:equal_index+1]
if kword in keywords:
return kword
else:
print "Invalid keyword at line:"
print line
sys.exit()
return None

def printdb( db, text ):
print " "
print "db %s = " % text
print db
print " "

if __name__ == '__main__':
csv_it()

================================================== ==

Thanks
Phill
Sep 7 '05 #27

P: n/a
Phill Atwood wrote:
Newbie question:

I have a dictionary called "rec". And a list called "db". db is my
database. rec are to be records in the database. In a loop I'm trying to
create a record and add it to my database. The key stmt is

db.append( rec )

This works initially but it seems that instead of copying the values in
rec and adding it to db, only a reference of rec is added to db. Thus
when I reassign rec with new data and then do another append I end up
with two records in my database but now the both contain the same data,
namely the latest version or rec.

So how do I add a dictionary into a list by value rather than by reference?

The complete code is here:

[code snipped]

I see you do a rec.clear() to clear out the contents of one record
before creating a new one. Python only *ever* uses references, so why
not just use

rec = {}

instead of rec.clear()?

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

Sep 7 '05 #28

P: n/a

"Phill Atwood" <fa*********@nowhere.org> wrote in message
news:Wo******************@news20.bellglobal.com...
def csv_it():
db = [] # the entire database of records
rec = {} # a single rec: a dictionary of field names and data pairs
Move this line
fields = [] # list of field names collected so far for current record
for line in open(inputfile):
to here
kword = getkeyword(line) # get keyword (or field name) .... # Now clear current record
fields = []
rec.clear()
and delete this
dummylist = []


and I think you will have what you want (or close).
The initial fields = [] line could be moved also, I believe, without
thoroughly reading your code.

Terry J. Reedy

Sep 7 '05 #29

P: n/a

Phill Atwood wrote:
[...]
So how do I add a dictionary into a list by value rather than
by reference?
Is rec.items() what you want? It returns a list of (key, value)
tuples.

The complete code is here:

[...]

Looks like you could use Python's ConfigParser module.

http://docs.python.org/lib/module-ConfigParser.html
--
--Bryan
Sep 7 '05 #30

P: n/a
I was trying to test the send() vs sendall() like this:

x=send(data)
print len(data)-x > 0 ? (when the code fails)

but I could not reproduce the failures anymore.
As if the lan got "refreshed" after the first
using of sendall() instead of send().

Btw, why we need send() if there is sendall()?

Sep 7 '05 #31

P: n/a
n00m wrote:
Btw, why we need send() if there is sendall()?


Mostly because sendall() can block, even if you do all the
select() and setblocking() magic. That's no problem in the
threaded architecture we're using, but a deal-breaker for a
single-threaded server.

--
--Bryan
Sep 7 '05 #32

P: n/a
Thanks, Bryan, for the details!

Btw, the newest oops in the topic's subject is:
the code does not work in the case of:

sqls_host, sqls_port = '192.168.0.8', 1433
proxy_host, proxy_port = '192.168.0.3', 1434
## proxy_host, proxy_port = '127.0.0.1', 1434
## proxy_host, proxy_port = '', 1434

I.e. when both Python and vbs script run on one machine
(with ip = 192.168.0.3) and SQL Server runs on another
(with ip = 192.168.0.8)

How namely it does not work:
in the idle window only one line is printed:

VB_SCRIPT:.........

that's all. No errors from Python. After timeout expires
I get an error message from VBS (smth like preHandShake()
failed; I've never seen it before).

I just wonder MUST (or not) it work at all (IN THEORY)?

PS: again, without Python vbs and sql server contact with
each other PERFECTLY.

Sep 8 '05 #33

P: n/a
n00m wrote:
[...]
Btw, the newest oops in the topic's subject is:
the code does not work in the case of:

sqls_host, sqls_port = '192.168.0.8', 1433
proxy_host, proxy_port = '192.168.0.3', 1434
## proxy_host, proxy_port = '127.0.0.1', 1434
## proxy_host, proxy_port = '', 1434

I.e. when both Python and vbs script run on one machine
(with ip = 192.168.0.3) and SQL Server runs on another
(with ip = 192.168.0.8)

How namely it does not work:
in the idle window only one line is printed:

VB_SCRIPT:.........

that's all. No errors from Python. After timeout expires
I get an error message from VBS (smth like preHandShake()
failed; I've never seen it before).

I just wonder MUST (or not) it work at all (IN THEORY)?


No theoretically-must-or-even-should-work solution is generally
possible. Protocols can thwart proxies by using addresses that
they transfer within their payload-data. That's an essential
feature of some security protocols, such as SSL, and an
unfortunate consequence of some old or badly-designed protocols.

Were I a betting man (outside of Texas Hold'em, where I am), I'd
wager that your problem is more basic. The code you're running,
the settings you're setting, or -- well -- something there, is
not right.
--
--Bryan
Sep 9 '05 #34

This discussion thread is closed

Replies have been disabled for this discussion.