Help a C++ escapee!

Bjoern Schliessmann usenet-mail-0306.20.chr0n0ss at spamgourmet.com
Thu Jun 7 05:50:38 EDT 2007


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/core/documentation/howto/index.html

-- 
BOFH excuse #20:

divide-by-zero error




More information about the Python-list mailing list