472,958 Members | 2,145 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,958 software developers and data experts.

Help a C++ escapee!

Hi,

Can someone help me leave the murky c++ world and enter shiny pythonland?

I have a problem with importing and global variables, here's my code:

----------------------------------------
##server.py

#socket connections
from socketManager import*

network = CNetworkManager()
network.Listen()

--------------------------------------
##socketManager.py

from time import sleep
from socket import*

import threading
class CNetworkManager():
def __init__(self):
self.hostName = ""
self.portNumber = 15500
self.buffer = 500
self.serverAddress = ( self.hostName, self.portNumber )
self.maxClients = 2
## previous stuff to send to new client
self.serverData = []

self.serverSocket = socket ( AF_INET, SOCK_STREAM )
self.serverSocket.bind ( self.serverAddress )
print( "Socket started " )
self.serverSocket.listen ( self.maxClients )
print( "Server is waiting for a connection" )

def Listen(self):
self.threadArray =[]
self.ch = 0
while self.ch < self.maxClients:
#Create a thread listening to each socket
self.newThreadObject = CServerThread()
self.newThreadObject.start()
self. threadArray.append(self.newThreadObject)
self.ch=self.ch+1

class CServerThread(threading.Thread):
def run(self):
while (1):
self.clientSocket, self.clientAddress = network.accept()
print("New Client:", self.clientAddress)
if network.serverData:
for i in range(len(network.serverData)):
clientSocket.send(str(network.serverData[i]))
sleep(0.01)
else:
clientSocket.send("You are logged in")
print("Entering loop for client ", clientAddress )
while 1:
clientData = clientSocket.recv(Buffer)
if not clientData:
print( clientAddress + " has closed the connection" )
break
print( "%s says %s" % (clientAddress, clientData))
clientData = clientData + "~~"
network.serverData.append(clientData)
for i in range(len(network.serverData)):
clientSocket.send(str(network.serverData[i]))
sleep(0.01)
print("Ready to receive more data")

clientData.close()
break
network.serverSocket.close()
--------------------------------------------------

When run, I come unstuck here:

self.clientSocket, self.clientAddress = network.accept()

I get a nameError on 'network', yet it is one in the global namespace,
defined in server.py before CServerThread.Listen() is called.

In c++, I understood how to declare variables, here I have a problem. Its
like I need an extern statement from c++.

Can anyone clarify this for me?

Many thanks

Simon

__________________________________________________ _______________
Play your part in making history - Email Britain!
http://www.emailbritain.co.uk/

Jun 7 '07 #1
4 1113
Ant
Hi Simon,
When run, I come unstuck here:

self.clientSocket, self.clientAddress = network.accept()

I get a nameError on 'network', yet it is one in the global namespace,
defined in server.py before CServerThread.Listen() is called.
You have imported everything from socketManager in server.py, but
socketManager knows nothing about any globals defined in the server
module! You'd need to import it in socketManager.py:

from server import network

However this may not work, since you have circular dependencies in
your code - server requires socketManager and vice versa. Even if this
does work it is bad practice, and is an indication that your classes
are in the wrong modules, or that your classes need refactoring
somewhat.

A simple solution would be to pass an instance of the CNetworkManager
into CServerThread. i.e.

....
def Listen(self):
self.threadArray =[]
self.ch = 0
while self.ch < self.maxClients:
#Create a thread listening to each socket
self.newThreadObject = CServerThread(self)
self.newThreadObject.start()
self. threadArray.append(self.newThreadObject)
self.ch=self.ch+1
class CServerThread(threading.Thread):
def __init__(self, network):
self.network = network

def run(self):
while (1):
self.clientSocket, self.clientAddress =
self.network.accept()

....

HTH.

--
Ant...

http://antroy.blogspot.com/

Jun 7 '07 #2
Hello,

Simon Pickles wrote:
Can someone help me leave the murky c++ world and enter shiny pythonland?
Welcome!
I have a problem with importing and global variables, here's my code:

[...]

When run, I come unstuck here:

self.clientSocket, self.clientAddress = network.accept()

I get a nameError on 'network', yet it is one in the global namespace,
defined in server.py before CServerThread.Listen() is called.
That won't work (as you found out :)). You need to make 'network'
available within socketManager.py. Each module on its own has a
namespace, there isn't such a thing as a global namespace that is
accessible from all modules, like you are used to in C or C++.

So when you access the variable 'network' in module socketManager it is
looked up in that module's namespace. When you read through
socketManager.py (without looking at any other code) you will see that
'network' isn't being defined anywhere. I would solve it like this:

Pass it as a parameter to CNetworkManager's and CServerThread's
constructor and store it as an instance variable, i.e. for CNetworkManager:

class CNetworkManager:
def __init__(self, network):
self.network = network
...

and then later pass it again to the thread you're creating.

Another way to have something a bit more like a global namespace would
be to create a new module, say we name it globals.py.

-------------------------
# globals.py

# initially, no network set
network = None
-------------------------

Each module that needs access to globals would then import the globals
module and access its variables. So, server.py would do

import globals
globals.network = CNetworkManager()
globals.network.Listen()

and socketManager.py would do

import globals

...
self.clientSocket, self.clientAddress = globals.network.accept()

(You could also selectively import the network variable of course with
"from globals import network").

Hope this helps,
Paul
Jun 7 '07 #3
Simon Pickles wrote:
from socket import *
Bad idea, can make conflicts in namespace.
import threading
There's absolutely no need to use threads for a server that accepts
multiple connections :)
class CNetworkManager():
Note that you create an "old style" class. For new style classes,
inherit from "object".
print("New Client:", self.clientAddress)
if network.serverData:
for i in range(len(network.serverData)):
clientSocket.send(str(network.serverData[i]))
sleep(0.01)
Using for like this is in most cases ugly and not needed. Better
would be to use here

for data in network.serverdata:
clientSocket.send(str(data))

It does the same. Remember, C++ needs an index in for, Python only
needs an iterable (e.g. a list or string) as for argument and does
the rest by itself.

BTW, what's the sleep for?
while 1:
clientData = clientSocket.recv(Buffer)
if not clientData:
print( clientAddress + " has closed the
connection" )
What exactly is the closing condition here? In my understanding, you
should always receive something, at least a "\n" or "\r\n".

Also note that comments and docstrings are cool, and parentheses around
the print statements' parameters are superfluous.
When run, I come unstuck here:

self.clientSocket, self.clientAddress =
network.accept()

I get a nameError on 'network', yet it is one in the global
namespace,
No, it's in global module namespace, not global namespace. Outside
of the module where it's defined, no one knows it, except you import
it explicitly there.
In c++, I understood how to declare variables, here I have a
problem. Its like I need an extern statement from c++.
Better

* use import or
* pass "network" using the constructor of the class using it or
* put it all in the same file.

Hope that helps.

BTW, using those low level functions you make yourself more hassle
than you really need. Have a look at this, it's mainly your server
programmed using Twisted framework[1]. I think that's much easier,
you can concentrate on your program instead of having to care about
connection and data receiving management.

------------------------------------------------------------------
#!/usr/bin/env python

from twisted.internet import protocol, reactor
from twisted.protocols import basic

class CNetwork(basic.LineReceiver):
def connectionMade(self):
print "New Client:", self.transport.getPeer().host
self.send = lambda x: self.transport.write(x+"\r\n")
if self.factory.server_data:
self.send("\r\n".join(self.factory.server_data))
else:
self.send("You are logged in")
print "Entering loop for client", self.transport.getPeer().host

def connectionLost(self, reason):
print self.transport.getPeer().host, "has closed the connection"

def dataReceived(self, data):
data = data.strip()
if not data:
self.transport.loseConnection()
return
print "%s says %r" % (self.transport.getPeer().host,
data)
self.factory.server_data.append(data + "~~")
print "Ready to receive more data"

class CNetworkFactory(protocol.Factory):
protocol = CNetwork
def __init__(self, max_clients):
self.max_clients = max_clients
self.connected_clients = 0
self.server_data = []

def startFactory(self):
print "Factory started -- server is waiting for a connection"

def main():
reactor.listenTCP(15500, CNetworkFactory(max_clients = 2))
reactor.run()

if __name__ == "__main__":
main()
------------------------------------------------------------------

You could also run this here by creating a server.py like yours,
importing only twisted.internet.reactor and the factory class and
passing the latter to reactor.listenTCP there.

Regards,
Björn

[1] http://twistedmatrix.com/projects/co...wto/index.html

--
BOFH excuse #20:

divide-by-zero error

Jun 7 '07 #4
On Jun 7, 1:59 am, "Simon Pickles" <sipick...@hotmail.comwrote:
Hi,

Can someone help me leave the murky c++ world and enter shiny pythonland?

I have a problem with importing and global variables, here's my code:
[snip!]
When run, I come unstuck here:

self.clientSocket, self.clientAddress = network.accept()

I get a nameError on 'network', yet it is one in the global namespace,
defined in server.py before CServerThread.Listen() is called.

In c++, I understood how to declare variables, here I have a problem. Its
like I need an extern statement from c++.

Can anyone clarify this for me?
The others have covered your problem. I'd just like to add a little
detail.

As the others have mentioned, global variables reside in their module
namespace. There is no truly "global" namespace, and that hasn't
really shown up as a problem in Python. There are two tricks to this:

1) Modules are only executed once, at the first import. Every
additional import merely gets the module object, but does not execute
the code again. Try adding a print statement outside all class and
function statements in a module, then import it multiple times.
You'll only see the results of the print statement once.

You can also start up python with the "-v" flag. Python will then
tell you whenever it executes a module.

This means that you can have a "global" module. Create a Python
module with all the variables that you want, and just import that
module in all places that need those variables. If you find yourself
stuffing a huge number of variables into your global module, you
probably need to rethink your program design.

Otherwise, put the global data in the various modules that create and
update it. Usually, your other code will only need to access that
data under more rare conditions.

If you absolutely need a module to be re-executed, the "reload"
function will do what you want.

2) Modules do not have to be imported at the start of the file. A
module import statement can occur any time code is executed. By
convention, we place the import statement at the beginning of the
block where we use it.

Remember that Python isn't C++. If you place an import statement in a
function, Python doesn't try to import that statement until the
function is called. This is very different from C/C++'s #include
preprocessor statements.

If you're having problems with circular references, the import
statement can usually
be moved inside of functions or methods that need them, or the files
can be refactored to get rid of the circular reference.

Here's something that shows both points. I started python by typing
in "python -v". There's a large number of imported modules that
Python automatically loads. After that finishes:
>>def spam(x):
.... x = 5 * x
.... import math # Math won't be imported until this function is
called
.... return math.pow(x, 2)
....
>>spam(1) # This should import the math module, executing its contents
import math # builtin
25.0
>>spam(2) # spam() will now use the previously import math module. (This is fast)
100.0

Hope this helps!

--Jason

Jun 7 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
by: Dave | last post by:
After following Microsofts admonition to reformat my system before doing a final compilation of my app I got many warnings/errors upon compiling an rtf file created in word. I used the Help...
6
by: wukexin | last post by:
Help me, good men. I find mang books that introduce bit "mang header files",they talk too bit,in fact it is my too fool, I don't learn it, I have do a test program, but I have no correct doing...
3
by: Colin J. Williams | last post by:
Python advertises some basic service: C:\Python24>python Python 2.4.1 (#65, Mar 30 2005, 09:13:57) on win32 Type "help", "copyright", "credits" or "license" for more information. >>> With...
7
by: Corepaul | last post by:
Missing Help Files When I enter "recordset" as the keyword and search the Visual Basic Help index, I get many topics of interest in the resulting list. But there isn't any information available...
5
by: Steve | last post by:
I have written a help file (chm) for a DLL and referenced it using Help.ShowHelp My expectation is that a developer using my DLL would be able to access this help file during his development time...
8
by: Mark | last post by:
I have loaded Visual Studio .net on my home computer and my laptop, but my home computer has an abbreviated help screen not 2% of the help on my laptop. All the settings look the same on both...
10
by: JonathanOrlev | last post by:
Hello everybody, I wrote this comment in another message of mine, but decided to post it again as a standalone message. I think that Microsoft's Office 2003 help system is horrible, probably...
1
by: trunxnirvana007 | last post by:
'UPGRADE_WARNING: Array has a new behavior. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"' 'UPGRADE_WARNING: Couldn't resolve...
0
by: hitencontractor | last post by:
I am working on .NET Version 2003 making an SDI application that calls MS Excel 2003. I added a menu item called "MyApp Help" in the end of the menu bar to show Help-> About. The application...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.