Reputation: 484
I have set up a TCP server using the twisted example (with some modifications).
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
from os import path
import yaml
class User(LineReceiver):
def __init__(self,users):
self.users = users
self.name = None
def connectionMade(self):
print 'new connection'
self.sendLine('username:')
def connectionLost(self,reason):
print 'connection lost'
if not self.name == None:
msg = '%s has disconnected' % (self.name)
print msg
self.toAll(msg,None)
del self.users[self.name]
def lineRecieved(self,line):
print line
if self.name == None:
self.setName(line)
else:
self.toChat(line)
def toAll(self,msg,to_self):
for name, protocol in self.users.iteritems():
if protocol == self and not to_self == None:
self.sendLine(to_self)
else:
protocol.sendLine(msg)
def setName(self,name):
if self.users.has_key(name):
self.sendLine('username in use')
return
elif ' ' in name:
self.sendLine('no spaces!')
return
print 'new user %s' % (name)
self.sendLine('logged in as %s' % (name))
self.name = name
self.users[name] = self
def toChat(self,message):
msg = '<%s> %s' % (self.name,message)
print msg
to_self = '<%s (you)> %s' % (self.name,message)
self.toAll(msg,to_self)
class Main(Factory):
def __init__(self,motd=None):
self.users = {}
self.motd = motd
print 'loaded, waiting for connections...'
def buildProtocol(self,addr):
return User(self.users)
if not path.isfile('config.yml'):
open('config.yml','w').write('port: 4444\nmotd: don\'t spam')
with open('config.yml','r') as f:
dump = yaml.load(f.read())
motd = dump['motd']
port = dump['port']
reactor.listenTCP(port,Main(motd=motd))
reactor.run()
I was wondering how I would be able to connect to it? I've tried adapting their example Echo client and Echo server, but my server only gives a giant error when data is sent back to it.
(The echo server is here and the echo client is here)
The client I am using is
from twisted.internet import reactor
from twisted.internet.protocol import Protocol,ClientFactory
class Main(Protocol):
def dataReceived(self,data):
print data
self.transport.write(data)
class MainFactory(ClientFactory):
def buildProtocol(self,addr):
print 'connected'
return Main()
def clientConnectionLost(self,connector,reason):
print 'connection lost'
def clientConnectionFailed(self,connector,reason):
print 'connection failed'
reactor.connectTCP('localhost',4444,MainFactory())
reactor.run()
Here is a picture of the error
What do I need to do to send data back to the server? What class do I need to inherit from?
Upvotes: 0
Views: 3876
Reputation: 365657
The problem is a simple typo.
LineReceiver
calls its lineReceived
method on each line. You're supposed to override that. But you don't, you define lineRecieved
instead. So, you get the default implementation, which raises NotImplemented
.
If you fix that, your code is still more than a little odd. Trace through the communication.
The client connects, which calls the server's User.connectionMade
, which does this:
self.sendLine('username:')
So the client gets that in Main.dataReceived
and does this:
self.transport.write(data)
So, it's sending the prompt back as a response.
The server will receive that in lineReceived
(once you fix the name) and do this:
if self.name == None:
self.setName(line)
So, you're going to set the username to 'username:'
.
Upvotes: 3